├── LICENSE.txt
├── README.md
├── config-server
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ └── ConfigApplication.java
│ └── resources
│ ├── application.properties
│ ├── lovnx-dev.properties
│ ├── lovnx-prod.properties
│ ├── lovnx-test.properties
│ └── lovnx.properties
├── eureka-sever
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ └── EurekaServer.java
│ └── resources
│ ├── application.properties
│ └── logback.xml
├── feign
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── feign
│ │ ├── FeignApplication.java
│ │ └── client
│ │ ├── FeignController.java
│ │ └── TestFeignClient.java
│ └── resources
│ └── application.yml
├── hystrix-dashboard
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── hystrix_dashboard
│ │ └── HystrixDashboardApplication.java
│ └── resources
│ └── application.yml
├── hystrix-feign
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── feign_hystrix
│ │ ├── FeignHystrixApplication.java
│ │ └── feign
│ │ ├── FeignController.java
│ │ └── TestFeignClient.java
│ └── resources
│ └── application.yml
├── hystrix-ribbon
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── hystrix
│ │ ├── HystrixApplication.java
│ │ └── normal
│ │ ├── HystrixController.java
│ │ └── HystrixService.java
│ └── resources
│ └── application.yml
├── pom.xml
├── ribbon
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ ├── RibbonApplication.java
│ │ └── web
│ │ └── ConsumerController.java
│ └── resources
│ └── application.properties
├── service-A
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ ├── A_Application.java
│ │ └── web
│ │ ├── ComputeController.java
│ │ └── TestController.java
│ └── resources
│ ├── application.properties
│ └── bootstrap.properties
├── service-B
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ ├── B_Application.java
│ │ ├── config
│ │ ├── DataSourceProperties.java
│ │ ├── DruidDataSourceConfig.java
│ │ └── SqlSessionFactoryConfig.java
│ │ ├── entity
│ │ ├── InterfaceLimit.java
│ │ └── InterfaceLimitExample.java
│ │ ├── mapper
│ │ └── InterfaceLimitMapper.java
│ │ ├── service
│ │ ├── InterfaceLimitService.java
│ │ └── impl
│ │ │ └── InterfaceLimitServiceImpl.java
│ │ ├── test
│ │ ├── ApiCallDemo.java
│ │ ├── ListenableFutureDemo.java
│ │ └── mytst.java
│ │ └── web
│ │ ├── ComputeController.java
│ │ ├── RateLimiter.java
│ │ └── RedisUtils.java
│ └── resources
│ ├── application.properties
│ └── mapper
│ └── InterfaceLimitMapper.xml
├── service-B2
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ ├── B2_Application.java
│ │ └── web
│ │ └── ComputeController.java
│ └── resources
│ ├── application.properties
│ └── logback.xml
├── service-admin
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── lovnx
│ │ ├── NotifierConfiguration.java
│ │ └── SpringBootAdminApplication.java
│ └── resources
│ ├── application.properties
│ └── logback.xml
├── sleuth
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── lovnx
│ │ │ └── Sleuth_Application.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── sleuth
│ └── AppTest.java
├── turbine
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── turbine
│ │ └── TurbineApplication.java
│ └── resources
│ └── application.yml
└── zuul
├── pom.xml
└── src
└── main
├── java
└── com
│ └── lovnx
│ ├── ZuulApplication.java
│ └── filter
│ ├── ErrorFilter.java
│ ├── FirstFilter.java
│ ├── ResultFilter.java
│ └── SecondFilter.java
└── resources
└── application.properties
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |
4 | spring-cloud 微服务组件demo
5 | ===
6 |
7 | 
8 |
9 |
10 |
11 | 工程名 描述 端口
12 |
13 |
14 | eureka-server 服务发现与注册中心 7070
15 |
16 |
17 | ribbon 负载均衡器 7071
18 |
19 |
20 | config-server 配置管理中心 7072
21 |
22 |
23 | zuul 动态路由器 7073
24 |
25 |
26 | service-A A服务,用来测试服务间调用与路由 7074
27 |
28 |
29 | service-B B服务,整合Mybatis、PageHelper、Redis,整合接口限速方案,可选google Guava RateLimiter与自实现 7075
30 |
31 |
32 | service-B2 B2服务,与B服务serviceId相同,用来测试负载均衡和容错 7076
33 |
34 |
35 | hystrix-ribbon 负载均衡器的容错测试 7077
36 |
37 |
38 | feign 声明式、模板化的HTTP客户端,可用来做负载均衡,较轻量 7078
39 |
40 |
41 | hystrix-feign feign的容错测试 7079
42 |
43 |
44 | hystrix-dashboard hystrix可视化监控台 7080
45 |
46 |
47 | turbine 集群下hystrix可视化监控台 7081
48 |
49 |
50 | sleuth 服务链路追踪 7082
51 |
52 |
53 | service-admin spring boot admin监控台 7088
54 |
55 |
56 |
57 | 环境:JDK1.8
58 | 组件依赖版本:Camden.SR5
59 |
60 | ```
61 |
62 | UTF-8
63 | 1.8
64 |
65 | ```
66 |
67 | 有关项目启动和配置的说明:
68 |
69 | 1、最先启动的是eureka-server,并且你需要在整个测试过程中保持它的启动状态,因为它是注册中心,大多数服务必须依赖于它才能实现必要的功能。
70 | 2、如果你想测试配置中心,可以先启动config-server,再启动service-A,按照规则来获取config-server的配置信息。
71 | 3、如果你想测试负载均衡,则需启动ribbon、service-B、service-B2工程,在ribbon中配置自己需要的负载均衡策略,配置方法见:http://blog.csdn.net/rickiyeat/article/details/64918756
72 | 4、如果你想测试路由,则需启动zuul工程,另外需保证service-B、service-B2、service-A其中一个或者多个工程处于启动状态,按照zuul工程的配置文件来进行相应的操作。
73 | 5、如果你想查看spring boot admin监控台,则需启动service-admin、service-B工程,注意,spring boot admin工程需至少运行于JDK8环境。
74 | 6、如果你想测试熔断功能,则需启动hystrix-ribbon与ribbon或者feign与hystrix-feign工程。
75 | 7、如果你想查看断路器的监控台,请启动hystrix-dashboard(单机)和turbine(集群)工程,使用方法代码注释有写。
76 | 8、如果你想知道服务之间的调用情况,启动sleuth、service-B2、service-A。
77 |
78 | 联系方式:qq930999349
79 |
--------------------------------------------------------------------------------
/config-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | config-server
9 | jar
10 |
11 |
12 |
13 | UTF-8
14 | 1.7
15 |
16 |
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-test
22 | test
23 |
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-config-server
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | org.springframework.cloud
36 | spring-cloud-dependencies
37 | Camden.SR5
38 | pom
39 | import
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-maven-plugin
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/config-server/src/main/java/com/lovnx/ConfigApplication.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.config.server.EnableConfigServer;
6 |
7 | @EnableConfigServer
8 | @SpringBootApplication
9 | public class ConfigApplication {
10 |
11 | public static void main(String[] args) {
12 | new SpringApplicationBuilder(ConfigApplication.class).web(true).run(args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/config-server/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=config-server
2 | server.port=7072
3 |
4 | # git\u8FDC\u7A0B\u914D\u7F6E
5 | #spring.cloud.config.server.git.uri=http://git.oschina.net/Lovnx/SC/
6 | #spring.cloud.config.server.git.searchPaths=/config-repo
7 | #spring.cloud.config.server.git.username=username
8 | #spring.cloud.config.server.git.password=password
9 |
10 | # \u6FC0\u6D3B\u672C\u5730\u914D\u7F6E
11 | spring.profiles.active=native
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/config-server/src/main/resources/lovnx-dev.properties:
--------------------------------------------------------------------------------
1 | from=local-dev
--------------------------------------------------------------------------------
/config-server/src/main/resources/lovnx-prod.properties:
--------------------------------------------------------------------------------
1 | from=local-prod
--------------------------------------------------------------------------------
/config-server/src/main/resources/lovnx-test.properties:
--------------------------------------------------------------------------------
1 | from=local-test
--------------------------------------------------------------------------------
/config-server/src/main/resources/lovnx.properties:
--------------------------------------------------------------------------------
1 | from=local
--------------------------------------------------------------------------------
/eureka-sever/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | eureka-sever
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-test
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-eureka-server
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-dependencies
36 | Camden.SR5
37 | pom
38 | import
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-maven-plugin
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/eureka-sever/src/main/java/com/lovnx/EurekaServer.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
6 |
7 | @EnableEurekaServer
8 | @SpringBootApplication
9 | public class EurekaServer {
10 |
11 | public static void main(String[] args) {
12 | new SpringApplicationBuilder(EurekaServer.class).web(true).run(args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/eureka-sever/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=eureka-server
2 | server.port=7070
3 | #eureka.instance.hostname=localhost
4 |
5 | eureka.client.register-with-eureka=false
6 | eureka.client.fetch-registry=false
7 | eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
8 |
--------------------------------------------------------------------------------
/eureka-sever/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ${LOG_HOME}/${LOG_PREFIX}-info.log
14 |
15 |
16 | ${LOG_HOME}/${LOG_PREFIX}-info-%d{yyyyMMdd}.log.%i
17 |
18 | 100MB
19 | 30
20 | 20GB
21 |
22 |
23 |
24 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
25 |
26 |
27 |
28 |
29 |
30 |
31 | ERROR
32 |
33 | ${LOG_HOME}/${LOG_PREFIX}-error.log
34 |
35 |
36 | ${LOG_HOME}/${LOG_PREFIX}-error-%d{yyyyMMdd}.log.%i
37 |
38 | 100MB
39 | 30
40 | 20GB
41 |
42 |
43 |
44 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
45 |
46 |
47 |
48 |
49 |
50 |
51 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/feign/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | feign
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 3.8.1
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-eureka
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-starter-feign
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-actuator
37 |
38 |
39 |
40 |
41 | org.springframework.cloud
42 | spring-cloud-starter-hystrix
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.cloud
50 | spring-cloud-dependencies
51 | Camden.SR5
52 | pom
53 | import
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/feign/src/main/java/com/feign/FeignApplication.java:
--------------------------------------------------------------------------------
1 | package com.feign;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.netflix.feign.EnableFeignClients;
7 |
8 | @SpringBootApplication
9 | @EnableFeignClients
10 | @EnableDiscoveryClient
11 | public class FeignApplication {
12 | public static void main(String[] args) {
13 |
14 | SpringApplication.run(FeignApplication.class, args);
15 | }
16 | }
--------------------------------------------------------------------------------
/feign/src/main/java/com/feign/client/FeignController.java:
--------------------------------------------------------------------------------
1 | package com.feign.client;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | @RestController
10 | public class FeignController {
11 | @Autowired
12 | private TestFeignClient testFeignClient;
13 |
14 | @RequestMapping(value = "/add" , method = RequestMethod.GET)
15 | public String add(@RequestParam Integer a,@RequestParam Integer b) {
16 | String string = this.testFeignClient.add(a,b);
17 | return string;
18 | }
19 | }
--------------------------------------------------------------------------------
/feign/src/main/java/com/feign/client/TestFeignClient.java:
--------------------------------------------------------------------------------
1 | package com.feign.client;
2 |
3 | import org.springframework.cloud.netflix.feign.FeignClient;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 |
7 | @FeignClient(name = "SERVICE-B")
8 | public interface TestFeignClient {
9 |
10 | @RequestMapping("/add")
11 | public String add(@RequestParam("a") Integer a,@RequestParam("b") Integer b);
12 | }
--------------------------------------------------------------------------------
/feign/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 7078
3 | spring:
4 | application:
5 | name: my-feign
6 | eureka:
7 | client:
8 | serviceUrl:
9 | defaultZone: http://localhost:7070/eureka/
10 | instance:
11 | preferIpAddress: true
12 | ribbon:
13 | eureka:
14 | enabled: true # 默认为true。如果设置为false,Ribbon将不会从Eureka中获得服务列表,而是使用静态配置的服务列表。静态服务列表可使用:.ribbon.listOfServers来指定。参考:http://projects.spring.io/spring-cloud/docs/1.0.3/spring-cloud.html#spring-cloud-ribbon-without-eureka
15 |
--------------------------------------------------------------------------------
/hystrix-dashboard/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | hystrix-dashboard
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 3.8.1
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-hystrix-dashboard
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-actuator
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-dependencies
41 | Camden.SR5
42 | pom
43 | import
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/hystrix-dashboard/src/main/java/com/hystrix_dashboard/HystrixDashboardApplication.java:
--------------------------------------------------------------------------------
1 | package com.hystrix_dashboard;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
6 |
7 | /**
8 | * 测试步骤:
9 | * 1. 访问http://localhost:8030/hystrix.stream 可以查看Dashboard
10 | * 2. 在上面的输入框填入: http://想监控的服务:端口/hystrix.stream进行测试
11 | * 注意:首先要先调用一下想监控的服务的API,否则将会显示一个空的图表.
12 | */
13 | @SpringBootApplication
14 | @EnableHystrixDashboard
15 | public class HystrixDashboardApplication {
16 | public static void main(String[] args) {
17 | new SpringApplicationBuilder(HystrixDashboardApplication.class).web(true).run(args);
18 | }
19 | }
--------------------------------------------------------------------------------
/hystrix-dashboard/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: hystrix-dashboard
4 | server:
5 | port: 7080
6 |
7 | #进入页面http://localhost:7080/hystrix.stream
8 | #监控http://localhost:7077/hystrix.stream
9 |
--------------------------------------------------------------------------------
/hystrix-feign/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | hystrix-feign
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 3.8.1
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-eureka
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-starter-feign
32 |
33 |
34 |
35 |
36 | org.springframework.cloud
37 | spring-cloud-starter-ribbon
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-actuator
43 |
44 |
45 |
46 |
47 | org.springframework.cloud
48 | spring-cloud-starter-hystrix
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.springframework.cloud
56 | spring-cloud-dependencies
57 | Camden.SR5
58 | pom
59 | import
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-maven-plugin
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/hystrix-feign/src/main/java/com/feign_hystrix/FeignHystrixApplication.java:
--------------------------------------------------------------------------------
1 | package com.feign_hystrix;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 | import org.springframework.cloud.netflix.feign.EnableFeignClients;
8 |
9 | @SpringBootApplication
10 | @EnableFeignClients
11 | @EnableDiscoveryClient
12 | @EnableCircuitBreaker
13 | public class FeignHystrixApplication {
14 | public static void main(String[] args) {
15 |
16 | SpringApplication.run(FeignHystrixApplication.class, args);
17 | }
18 | }
--------------------------------------------------------------------------------
/hystrix-feign/src/main/java/com/feign_hystrix/feign/FeignController.java:
--------------------------------------------------------------------------------
1 | package com.feign_hystrix.feign;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | @RestController
10 | public class FeignController {
11 | @Autowired
12 | private TestFeignClient testFeignClient;
13 |
14 | @RequestMapping(value = "/add" , method = RequestMethod.GET)
15 | public String add(@RequestParam("a") Integer a,@RequestParam("b") Integer b) {
16 | String string = this.testFeignClient.add(a,b);
17 | return string;
18 | }
19 | }
--------------------------------------------------------------------------------
/hystrix-feign/src/main/java/com/feign_hystrix/feign/TestFeignClient.java:
--------------------------------------------------------------------------------
1 | package com.feign_hystrix.feign;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 |
10 | import com.feign_hystrix.feign.TestFeignClient.HystrixClientFallback;
11 |
12 |
13 | @FeignClient(name = "service-B",fallback = HystrixClientFallback.class)
14 | public interface TestFeignClient {
15 |
16 | @RequestMapping("/add")
17 | public String add(@RequestParam("a") Integer a,@RequestParam("b") Integer b);
18 |
19 | @Component
20 | static class HystrixClientFallback implements TestFeignClient {
21 | private static final Logger LOGGER = LoggerFactory.getLogger(HystrixClientFallback.class);
22 |
23 | @Override
24 | public String add(Integer a, Integer b) {
25 | HystrixClientFallback.LOGGER.info("异常发生,进入fallback方法,接收的参数: {},{}",a,b);
26 | return "feign-hystrix";
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/hystrix-feign/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 7079
3 | spring:
4 | application:
5 | name: feign-hystrix
6 | eureka:
7 | client:
8 | serviceUrl:
9 | defaultZone: http://localhost:7070/eureka/
10 | instance:
11 | hostname:feign
12 | ribbon:
13 | eureka:
14 | enabled: true
15 |
--------------------------------------------------------------------------------
/hystrix-ribbon/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | hystrix-ribbon
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 3.8.1
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-eureka
27 |
28 |
29 |
30 |
31 | org.springframework.cloud
32 | spring-cloud-starter-ribbon
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-actuator
38 |
39 |
40 |
41 |
42 | org.springframework.cloud
43 | spring-cloud-starter-hystrix
44 |
45 |
46 |
47 |
48 |
49 |
50 | org.springframework.cloud
51 | spring-cloud-dependencies
52 | Camden.SR5
53 | pom
54 | import
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/hystrix-ribbon/src/main/java/com/hystrix/HystrixApplication.java:
--------------------------------------------------------------------------------
1 | package com.hystrix;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.web.client.RestTemplate;
10 |
11 | @SpringBootApplication
12 | @EnableDiscoveryClient
13 | @EnableCircuitBreaker
14 | public class HystrixApplication {
15 | /**
16 | * 实例化RestTemplate,通过@LoadBalanced注解开启均衡负载能力.
17 | * @return restTemplate
18 | */
19 | @Bean
20 | @LoadBalanced
21 | public RestTemplate restTemplate() {
22 | return new RestTemplate();
23 | }
24 |
25 | public static void main(String[] args) {
26 | SpringApplication.run(HystrixApplication.class, args);
27 | }
28 | }
--------------------------------------------------------------------------------
/hystrix-ribbon/src/main/java/com/hystrix/normal/HystrixController.java:
--------------------------------------------------------------------------------
1 | package com.hystrix.normal;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RestController
9 | public class HystrixController {
10 |
11 | @Autowired
12 | private HystrixService ribbonHystrixService;
13 |
14 | @RequestMapping("/hystrix")
15 | public String findById(@RequestParam Integer a,@RequestParam Integer b) {
16 | return this.ribbonHystrixService.findById(a,b);
17 | }
18 | }
--------------------------------------------------------------------------------
/hystrix-ribbon/src/main/java/com/hystrix/normal/HystrixService.java:
--------------------------------------------------------------------------------
1 | package com.hystrix.normal;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.bind.annotation.RequestParam;
8 | import org.springframework.web.client.RestTemplate;
9 |
10 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
11 |
12 | @Service
13 | public class HystrixService {
14 | @Autowired
15 | private RestTemplate restTemplate;
16 | private static final Logger LOGGER = LoggerFactory.getLogger(HystrixService.class);
17 |
18 | /**
19 | * 使用@HystrixCommand注解指定当该方法发生异常时调用的方法
20 | */
21 | @HystrixCommand(fallbackMethod = "fallback")
22 | public String findById(@RequestParam Integer a,@RequestParam Integer b) {
23 | return restTemplate.getForEntity("http://SERVICE-B/add?a="+a+"&b="+b, String.class).getBody();
24 | }
25 |
26 | /**
27 | * hystrix fallback方法
28 | */
29 | public String fallback(@RequestParam Integer a,@RequestParam Integer b) {
30 | HystrixService.LOGGER.info("异常发生,进入fallback方法,接收的参数:id = {}", "qqq");
31 | return "出错了 a=" + a + " b=" + b;
32 | }
33 | }
--------------------------------------------------------------------------------
/hystrix-ribbon/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 7077
3 | spring:
4 | application:
5 | name: hystrix
6 | eureka:
7 | client:
8 | serviceUrl:
9 | defaultZone: http://localhost:7070/eureka/
10 | instance:
11 | hostname:ribbon
12 | ribbon:
13 | eureka:
14 | enabled: true
15 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 | pom
8 |
9 | ribbon
10 | eureka-sever
11 | config-server
12 | zuul
13 | service-A
14 | service-B
15 | service-B2
16 | hystrix-ribbon
17 | feign
18 | hystrix-feign
19 | hystrix-dashboard
20 | turbine
21 | service-admin
22 | sleuth
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-parent
28 | 1.5.2.RELEASE
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ribbon/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | ribbon
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | org.springframework.cloud
19 | spring-cloud-starter-ribbon
20 |
21 |
22 | org.springframework.cloud
23 | spring-cloud-starter-eureka
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-web
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.cloud
41 | spring-cloud-dependencies
42 | Camden.SR5
43 | pom
44 | import
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-maven-plugin
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/ribbon/src/main/java/com/lovnx/RibbonApplication.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.web.client.RestTemplate;
9 |
10 | import com.netflix.loadbalancer.IRule;
11 | import com.netflix.loadbalancer.RandomRule;
12 |
13 | @SpringBootApplication
14 | @EnableDiscoveryClient
15 | public class RibbonApplication {
16 |
17 | @Bean
18 | @LoadBalanced
19 | RestTemplate restTemplate() {
20 | return new RestTemplate();
21 | }
22 |
23 | @Bean
24 | public IRule ribbonRule() {
25 | return new RandomRule();
26 | }
27 |
28 | public static void main(String[] args) {
29 | SpringApplication.run(RibbonApplication.class, args);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/ribbon/src/main/java/com/lovnx/web/ConsumerController.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RequestMethod;
7 | import org.springframework.web.bind.annotation.RequestParam;
8 | import org.springframework.web.bind.annotation.RestController;
9 | import org.springframework.web.client.RestTemplate;
10 |
11 | @RestController
12 | public class ConsumerController {
13 |
14 | @Autowired
15 | private RestTemplate restTemplate;
16 |
17 | @Autowired
18 | private LoadBalancerClient loadBalancerClient;
19 |
20 | @RequestMapping(value = "/add", method = RequestMethod.GET)
21 | public String add(@RequestParam Integer a,@RequestParam Integer b) {
22 | this.loadBalancerClient.choose("service-B");//随机访问策略
23 | return restTemplate.getForEntity("http://service-B/add?a="+a+"&b="+b, String.class).getBody();
24 |
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/ribbon/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=ribbon
2 | server.port=7071
3 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
4 |
5 | service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
6 |
7 | #ribbon.eureka.enabled=false
--------------------------------------------------------------------------------
/service-A/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | service-A
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | org.springframework.cloud
19 | spring-cloud-starter-eureka
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-test
25 | test
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-starter-config
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-web
34 |
35 |
36 | org.springframework.cloud
37 | spring-cloud-starter-zipkin
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.springframework.cloud
45 | spring-cloud-dependencies
46 | Camden.SR5
47 | pom
48 | import
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-maven-plugin
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/service-A/src/main/java/com/lovnx/A_Application.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @EnableDiscoveryClient
8 | @SpringBootApplication
9 | public class A_Application {
10 |
11 | public static void main(String[] args) {
12 | new SpringApplicationBuilder(A_Application.class).web(true).run(args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/service-A/src/main/java/com/lovnx/web/ComputeController.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.cloud.client.ServiceInstance;
6 | import org.springframework.cloud.client.discovery.DiscoveryClient;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 | import org.springframework.web.bind.annotation.RequestParam;
10 | import org.springframework.web.bind.annotation.RestController;
11 | import org.springframework.web.client.RestTemplate;
12 |
13 | @RestController
14 | public class ComputeController {
15 |
16 | private final Logger logger = Logger.getLogger(getClass());
17 |
18 | @Autowired
19 | private DiscoveryClient client;
20 |
21 | @RequestMapping(value = "/add" ,method = RequestMethod.GET)
22 | public String add(@RequestParam Integer a, @RequestParam Integer b) {
23 | ServiceInstance instance = client.getLocalServiceInstance();
24 | Integer r = a + b;
25 | logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
26 | return "From Service-A, Result is " + r;
27 | }
28 |
29 | //A服务调用B服务
30 | @RequestMapping(value="testServiceB",method=RequestMethod.GET)
31 | public String testServiceB(@RequestParam Integer a,@RequestParam Integer b){
32 | RestTemplate restTemplate=new RestTemplate();
33 | return restTemplate.getForObject("http://localhost:7075/add?a="+a+"&b="+b, String.class);
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/service-A/src/main/java/com/lovnx/web/TestController.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.cloud.context.config.annotation.RefreshScope;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RefreshScope
9 | @RestController
10 | class TestController {
11 |
12 | @Value("${from}")
13 | private String from;
14 |
15 | @RequestMapping("/from")
16 | public String from() {
17 |
18 | return this.from;
19 | }
20 |
21 | public void setFrom(String from) {
22 | this.from = from;
23 | }
24 |
25 | public String getFrom() {
26 | return from;
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/service-A/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #spring.application.name=service-A
2 |
3 | #server.port=2222
4 |
5 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
6 |
7 | spring.zipkin.base-url=http://localhost:7082
--------------------------------------------------------------------------------
/service-A/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=service-A
2 | spring.cloud.config.name=lovnx
3 | spring.cloud.config.profile=dev
4 | spring.cloud.config.label=master
5 | spring.cloud.config.uri=http://localhost:7072/
6 |
7 | server.port=7074
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/service-B/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | service-B
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | org.springframework.cloud
19 | spring-cloud-starter-eureka
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-test
25 | test
26 |
27 |
28 |
29 |
30 | com.google.guava
31 | guava
32 | 14.0.1
33 |
34 |
35 |
36 | org.apache.commons
37 | commons-lang3
38 | 3.5
39 |
40 |
41 |
42 | redis.clients
43 | jedis
44 |
45 |
46 |
47 | org.mybatis.spring.boot
48 | mybatis-spring-boot-starter
49 | 1.2.0
50 |
51 |
52 | com.github.pagehelper
53 | pagehelper-spring-boot-starter
54 | 1.1.0
55 |
56 |
57 |
58 |
59 | com.alibaba
60 | druid
61 | 1.0.28
62 |
63 |
64 | mysql
65 | mysql-connector-java
66 | 5.1.40
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | org.springframework.cloud
75 | spring-cloud-dependencies
76 | Camden.SR5
77 | pom
78 | import
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | org.springframework.boot
87 | spring-boot-maven-plugin
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/B_Application.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @EnableDiscoveryClient
8 | @SpringBootApplication
9 | public class B_Application {
10 |
11 | public static void main(String[] args) {
12 | new SpringApplicationBuilder(B_Application.class).web(true).run(args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/config/DataSourceProperties.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.config;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 |
5 | @ConfigurationProperties(prefix = DataSourceProperties.DS, ignoreUnknownFields = false)
6 | public class DataSourceProperties {
7 | //对应配置文件里的配置键
8 | final static String DS="mysqldb.datasource";
9 |
10 | private String url;
11 | private String username;
12 | private String password;
13 | private String driverClassName;
14 | private int initialSize = 10;
15 | private int minIdle;
16 | private int maxIdle;
17 | private int maxActive;
18 | private int maxWait;
19 | private int timeBetweenEvictionRunsMillis;
20 | private int minEvictableIdleTimeMillis;
21 | private String validationQuery;
22 | private boolean testWhileIdle;
23 | private boolean testOnBorrow;
24 | private boolean testOnReturn;
25 | private boolean poolPreparedStatements;
26 | private int maxOpenPreparedStatements;
27 | private String filters;
28 |
29 | private String mapperLocations;
30 | private String typeAliasPackage;
31 |
32 | public String getDriverClassName() {
33 | return driverClassName;
34 | }
35 |
36 | public void setDriverClassName(String driverClassName) {
37 | this.driverClassName = driverClassName;
38 | }
39 |
40 | public String getUrl() {
41 | return url;
42 | }
43 |
44 | public void setUrl(String url) {
45 | this.url = url;
46 | }
47 |
48 | public String getUsername() {
49 | return username;
50 | }
51 |
52 | public void setUsername(String username) {
53 | this.username = username;
54 | }
55 |
56 | public String getPassword() {
57 | return password;
58 | }
59 |
60 | public void setPassword(String password) {
61 | this.password = password;
62 | }
63 |
64 | public int getInitialSize() {
65 | return initialSize;
66 | }
67 |
68 | public void setInitialSize(int initialSize) {
69 | this.initialSize = initialSize;
70 | }
71 |
72 | public int getMinIdle() {
73 | return minIdle;
74 | }
75 |
76 | public void setMinIdle(int minIdle) {
77 | this.minIdle = minIdle;
78 | }
79 |
80 | public int getMaxIdle() {
81 | return maxIdle;
82 | }
83 |
84 | public void setMaxIdle(int maxIdle) {
85 | this.maxIdle = maxIdle;
86 | }
87 |
88 | public int getMaxActive() {
89 | return maxActive;
90 | }
91 |
92 | public void setMaxActive(int maxActive) {
93 | this.maxActive = maxActive;
94 | }
95 |
96 | public int getMaxWait() {
97 | return maxWait;
98 | }
99 |
100 | public void setMaxWait(int maxWait) {
101 | this.maxWait = maxWait;
102 | }
103 |
104 | public int getTimeBetweenEvictionRunsMillis() {
105 | return timeBetweenEvictionRunsMillis;
106 | }
107 |
108 | public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
109 | this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
110 | }
111 |
112 | public int getMinEvictableIdleTimeMillis() {
113 | return minEvictableIdleTimeMillis;
114 | }
115 |
116 | public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
117 | this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
118 | }
119 |
120 | public String getValidationQuery() {
121 | return validationQuery;
122 | }
123 |
124 | public void setValidationQuery(String validationQuery) {
125 | this.validationQuery = validationQuery;
126 | }
127 |
128 | public boolean isTestWhileIdle() {
129 | return testWhileIdle;
130 | }
131 |
132 | public void setTestWhileIdle(boolean testWhileIdle) {
133 | this.testWhileIdle = testWhileIdle;
134 | }
135 |
136 | public boolean isTestOnBorrow() {
137 | return testOnBorrow;
138 | }
139 |
140 | public void setTestOnBorrow(boolean testOnBorrow) {
141 | this.testOnBorrow = testOnBorrow;
142 | }
143 |
144 | public boolean isTestOnReturn() {
145 | return testOnReturn;
146 | }
147 |
148 | public void setTestOnReturn(boolean testOnReturn) {
149 | this.testOnReturn = testOnReturn;
150 | }
151 |
152 | public boolean isPoolPreparedStatements() {
153 | return poolPreparedStatements;
154 | }
155 |
156 | public void setPoolPreparedStatements(boolean poolPreparedStatements) {
157 | this.poolPreparedStatements = poolPreparedStatements;
158 | }
159 |
160 | public int getMaxOpenPreparedStatements() {
161 | return maxOpenPreparedStatements;
162 | }
163 |
164 | public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
165 | this.maxOpenPreparedStatements = maxOpenPreparedStatements;
166 | }
167 |
168 | public String getFilters() {
169 | return filters;
170 | }
171 |
172 | public void setFilters(String filters) {
173 | this.filters = filters;
174 | }
175 |
176 | public String getMapperLocations() {
177 | return mapperLocations;
178 | }
179 |
180 | public void setMapperLocations(String mapperLocations) {
181 | this.mapperLocations = mapperLocations;
182 | }
183 |
184 | public String getTypeAliasPackage() {
185 | return typeAliasPackage;
186 | }
187 |
188 | public void setTypeAliasPackage(String typeAliasPackage) {
189 | this.typeAliasPackage = typeAliasPackage;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/config/DruidDataSourceConfig.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.config;
2 |
3 | import com.alibaba.druid.pool.DruidDataSource;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.context.annotation.Primary;
11 |
12 | import javax.sql.DataSource;
13 | import java.sql.SQLException;
14 |
15 | @Configuration
16 | @EnableConfigurationProperties(DataSourceProperties.class)
17 | public class DruidDataSourceConfig {
18 |
19 | private static Logger logger = LoggerFactory.getLogger(DruidDataSourceConfig.class);
20 |
21 | @Autowired
22 | private DataSourceProperties dataSourceProperties;
23 |
24 | @Bean
25 | @Primary
26 | public DataSource druidDataSource(){
27 | DruidDataSource datasource = new DruidDataSource();
28 |
29 | datasource.setUrl(dataSourceProperties.getUrl());
30 | datasource.setUsername(dataSourceProperties.getUsername());
31 | datasource.setPassword(dataSourceProperties.getPassword());
32 | datasource.setDriverClassName(dataSourceProperties.getDriverClassName());
33 | datasource.setInitialSize(dataSourceProperties.getInitialSize());
34 | datasource.setMinIdle(dataSourceProperties.getMinIdle());
35 | datasource.setMaxActive(dataSourceProperties.getMaxActive());
36 | datasource.setMaxWait(dataSourceProperties.getMaxWait());
37 | datasource.setTimeBetweenEvictionRunsMillis(dataSourceProperties.getTimeBetweenEvictionRunsMillis());
38 | datasource.setMinEvictableIdleTimeMillis(dataSourceProperties.getMinEvictableIdleTimeMillis());
39 | datasource.setValidationQuery(dataSourceProperties.getValidationQuery());
40 | datasource.setTestWhileIdle(dataSourceProperties.isTestWhileIdle());
41 | datasource.setTestOnBorrow(dataSourceProperties.isTestOnBorrow());
42 | datasource.setTestOnReturn(dataSourceProperties.isTestOnReturn());
43 | datasource.setPoolPreparedStatements(dataSourceProperties.isPoolPreparedStatements());
44 | try {
45 | datasource.setFilters(dataSourceProperties.getFilters());
46 | } catch (SQLException e) {
47 | logger.error("Druid configuration initialization filter error.", e);
48 | }
49 | return datasource;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/config/SqlSessionFactoryConfig.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.config;
2 |
3 | import org.apache.ibatis.session.SqlSessionFactory;
4 | import org.mybatis.spring.SqlSessionFactoryBean;
5 | import org.mybatis.spring.SqlSessionTemplate;
6 | import org.mybatis.spring.annotation.MapperScan;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
11 | import org.springframework.jdbc.datasource.DataSourceTransactionManager;
12 | import org.springframework.transaction.PlatformTransactionManager;
13 | import org.springframework.transaction.annotation.EnableTransactionManagement;
14 | import org.springframework.transaction.annotation.TransactionManagementConfigurer;
15 |
16 | import javax.sql.DataSource;
17 |
18 | @Configuration
19 | @EnableTransactionManagement
20 | @MapperScan("com.lovnx.mapper")
21 | public class SqlSessionFactoryConfig implements TransactionManagementConfigurer {
22 |
23 | @Autowired
24 | private DataSource dataSource;
25 |
26 | @Autowired
27 | private DataSourceProperties dataSourceProperties;
28 |
29 | /**
30 | * 创建sqlSessionFactoryBean 实例
31 | * 并且设置configtion 如驼峰命名.等等
32 | * 设置mapper 映射路径
33 | * 设置datasource数据源
34 | * @return
35 | * @throws Exception
36 | */
37 | @Bean(name = "sqlSessionFactory")
38 | public SqlSessionFactory createSqlSessionFactoryBean() throws Exception {
39 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
40 | /** 设置datasource */
41 | bean.setDataSource(dataSource);
42 | /** 设置typeAlias 包扫描路径 */
43 | bean.setTypeAliasesPackage(dataSourceProperties.getTypeAliasPackage());
44 |
45 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
46 | bean.setMapperLocations(resolver.getResources(dataSourceProperties.getMapperLocations()));
47 |
48 | return bean.getObject();
49 | }
50 |
51 | @Bean
52 | public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
53 | return new SqlSessionTemplate(sqlSessionFactory);
54 | }
55 |
56 | @Bean
57 | @Override
58 | public PlatformTransactionManager annotationDrivenTransactionManager() {
59 | return new DataSourceTransactionManager(dataSource);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/entity/InterfaceLimit.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.entity;
2 |
3 | public class InterfaceLimit {
4 | private Integer id;
5 |
6 | private Integer interfaceId;
7 |
8 | private Integer unitTime;
9 |
10 | private Integer unitNum;
11 |
12 | public Integer getId() {
13 | return id;
14 | }
15 |
16 | public void setId(Integer id) {
17 | this.id = id;
18 | }
19 |
20 | public Integer getInterfaceId() {
21 | return interfaceId;
22 | }
23 |
24 | public void setInterfaceId(Integer interfaceId) {
25 | this.interfaceId = interfaceId;
26 | }
27 |
28 | public Integer getUnitTime() {
29 | return unitTime;
30 | }
31 |
32 | public void setUnitTime(Integer unitTime) {
33 | this.unitTime = unitTime;
34 | }
35 |
36 | public Integer getUnitNum() {
37 | return unitNum;
38 | }
39 |
40 | public void setUnitNum(Integer unitNum) {
41 | this.unitNum = unitNum;
42 | }
43 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/entity/InterfaceLimitExample.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.entity;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class InterfaceLimitExample {
7 | protected String orderByClause;
8 |
9 | protected boolean distinct;
10 |
11 | protected List oredCriteria;
12 |
13 | public InterfaceLimitExample() {
14 | oredCriteria = new ArrayList();
15 | }
16 |
17 | public void setOrderByClause(String orderByClause) {
18 | this.orderByClause = orderByClause;
19 | }
20 |
21 | public String getOrderByClause() {
22 | return orderByClause;
23 | }
24 |
25 | public void setDistinct(boolean distinct) {
26 | this.distinct = distinct;
27 | }
28 |
29 | public boolean isDistinct() {
30 | return distinct;
31 | }
32 |
33 | public List getOredCriteria() {
34 | return oredCriteria;
35 | }
36 |
37 | public void or(Criteria criteria) {
38 | oredCriteria.add(criteria);
39 | }
40 |
41 | public Criteria or() {
42 | Criteria criteria = createCriteriaInternal();
43 | oredCriteria.add(criteria);
44 | return criteria;
45 | }
46 |
47 | public Criteria createCriteria() {
48 | Criteria criteria = createCriteriaInternal();
49 | if (oredCriteria.size() == 0) {
50 | oredCriteria.add(criteria);
51 | }
52 | return criteria;
53 | }
54 |
55 | protected Criteria createCriteriaInternal() {
56 | Criteria criteria = new Criteria();
57 | return criteria;
58 | }
59 |
60 | public void clear() {
61 | oredCriteria.clear();
62 | orderByClause = null;
63 | distinct = false;
64 | }
65 |
66 | protected abstract static class GeneratedCriteria {
67 | protected List criteria;
68 |
69 | protected GeneratedCriteria() {
70 | super();
71 | criteria = new ArrayList();
72 | }
73 |
74 | public boolean isValid() {
75 | return criteria.size() > 0;
76 | }
77 |
78 | public List getAllCriteria() {
79 | return criteria;
80 | }
81 |
82 | public List getCriteria() {
83 | return criteria;
84 | }
85 |
86 | protected void addCriterion(String condition) {
87 | if (condition == null) {
88 | throw new RuntimeException("Value for condition cannot be null");
89 | }
90 | criteria.add(new Criterion(condition));
91 | }
92 |
93 | protected void addCriterion(String condition, Object value, String property) {
94 | if (value == null) {
95 | throw new RuntimeException("Value for " + property + " cannot be null");
96 | }
97 | criteria.add(new Criterion(condition, value));
98 | }
99 |
100 | protected void addCriterion(String condition, Object value1, Object value2, String property) {
101 | if (value1 == null || value2 == null) {
102 | throw new RuntimeException("Between values for " + property + " cannot be null");
103 | }
104 | criteria.add(new Criterion(condition, value1, value2));
105 | }
106 |
107 | public Criteria andIdIsNull() {
108 | addCriterion("id is null");
109 | return (Criteria) this;
110 | }
111 |
112 | public Criteria andIdIsNotNull() {
113 | addCriterion("id is not null");
114 | return (Criteria) this;
115 | }
116 |
117 | public Criteria andIdEqualTo(Integer value) {
118 | addCriterion("id =", value, "id");
119 | return (Criteria) this;
120 | }
121 |
122 | public Criteria andIdNotEqualTo(Integer value) {
123 | addCriterion("id <>", value, "id");
124 | return (Criteria) this;
125 | }
126 |
127 | public Criteria andIdGreaterThan(Integer value) {
128 | addCriterion("id >", value, "id");
129 | return (Criteria) this;
130 | }
131 |
132 | public Criteria andIdGreaterThanOrEqualTo(Integer value) {
133 | addCriterion("id >=", value, "id");
134 | return (Criteria) this;
135 | }
136 |
137 | public Criteria andIdLessThan(Integer value) {
138 | addCriterion("id <", value, "id");
139 | return (Criteria) this;
140 | }
141 |
142 | public Criteria andIdLessThanOrEqualTo(Integer value) {
143 | addCriterion("id <=", value, "id");
144 | return (Criteria) this;
145 | }
146 |
147 | public Criteria andIdIn(List values) {
148 | addCriterion("id in", values, "id");
149 | return (Criteria) this;
150 | }
151 |
152 | public Criteria andIdNotIn(List values) {
153 | addCriterion("id not in", values, "id");
154 | return (Criteria) this;
155 | }
156 |
157 | public Criteria andIdBetween(Integer value1, Integer value2) {
158 | addCriterion("id between", value1, value2, "id");
159 | return (Criteria) this;
160 | }
161 |
162 | public Criteria andIdNotBetween(Integer value1, Integer value2) {
163 | addCriterion("id not between", value1, value2, "id");
164 | return (Criteria) this;
165 | }
166 |
167 | public Criteria andInterfaceIdIsNull() {
168 | addCriterion("interfaceId is null");
169 | return (Criteria) this;
170 | }
171 |
172 | public Criteria andInterfaceIdIsNotNull() {
173 | addCriterion("interfaceId is not null");
174 | return (Criteria) this;
175 | }
176 |
177 | public Criteria andInterfaceIdEqualTo(Integer value) {
178 | addCriterion("interfaceId =", value, "interfaceId");
179 | return (Criteria) this;
180 | }
181 |
182 | public Criteria andInterfaceIdNotEqualTo(Integer value) {
183 | addCriterion("interfaceId <>", value, "interfaceId");
184 | return (Criteria) this;
185 | }
186 |
187 | public Criteria andInterfaceIdGreaterThan(Integer value) {
188 | addCriterion("interfaceId >", value, "interfaceId");
189 | return (Criteria) this;
190 | }
191 |
192 | public Criteria andInterfaceIdGreaterThanOrEqualTo(Integer value) {
193 | addCriterion("interfaceId >=", value, "interfaceId");
194 | return (Criteria) this;
195 | }
196 |
197 | public Criteria andInterfaceIdLessThan(Integer value) {
198 | addCriterion("interfaceId <", value, "interfaceId");
199 | return (Criteria) this;
200 | }
201 |
202 | public Criteria andInterfaceIdLessThanOrEqualTo(Integer value) {
203 | addCriterion("interfaceId <=", value, "interfaceId");
204 | return (Criteria) this;
205 | }
206 |
207 | public Criteria andInterfaceIdIn(List values) {
208 | addCriterion("interfaceId in", values, "interfaceId");
209 | return (Criteria) this;
210 | }
211 |
212 | public Criteria andInterfaceIdNotIn(List values) {
213 | addCriterion("interfaceId not in", values, "interfaceId");
214 | return (Criteria) this;
215 | }
216 |
217 | public Criteria andInterfaceIdBetween(Integer value1, Integer value2) {
218 | addCriterion("interfaceId between", value1, value2, "interfaceId");
219 | return (Criteria) this;
220 | }
221 |
222 | public Criteria andInterfaceIdNotBetween(Integer value1, Integer value2) {
223 | addCriterion("interfaceId not between", value1, value2, "interfaceId");
224 | return (Criteria) this;
225 | }
226 |
227 | public Criteria andUnitTimeIsNull() {
228 | addCriterion("unitTime is null");
229 | return (Criteria) this;
230 | }
231 |
232 | public Criteria andUnitTimeIsNotNull() {
233 | addCriterion("unitTime is not null");
234 | return (Criteria) this;
235 | }
236 |
237 | public Criteria andUnitTimeEqualTo(Integer value) {
238 | addCriterion("unitTime =", value, "unitTime");
239 | return (Criteria) this;
240 | }
241 |
242 | public Criteria andUnitTimeNotEqualTo(Integer value) {
243 | addCriterion("unitTime <>", value, "unitTime");
244 | return (Criteria) this;
245 | }
246 |
247 | public Criteria andUnitTimeGreaterThan(Integer value) {
248 | addCriterion("unitTime >", value, "unitTime");
249 | return (Criteria) this;
250 | }
251 |
252 | public Criteria andUnitTimeGreaterThanOrEqualTo(Integer value) {
253 | addCriterion("unitTime >=", value, "unitTime");
254 | return (Criteria) this;
255 | }
256 |
257 | public Criteria andUnitTimeLessThan(Integer value) {
258 | addCriterion("unitTime <", value, "unitTime");
259 | return (Criteria) this;
260 | }
261 |
262 | public Criteria andUnitTimeLessThanOrEqualTo(Integer value) {
263 | addCriterion("unitTime <=", value, "unitTime");
264 | return (Criteria) this;
265 | }
266 |
267 | public Criteria andUnitTimeIn(List values) {
268 | addCriterion("unitTime in", values, "unitTime");
269 | return (Criteria) this;
270 | }
271 |
272 | public Criteria andUnitTimeNotIn(List values) {
273 | addCriterion("unitTime not in", values, "unitTime");
274 | return (Criteria) this;
275 | }
276 |
277 | public Criteria andUnitTimeBetween(Integer value1, Integer value2) {
278 | addCriterion("unitTime between", value1, value2, "unitTime");
279 | return (Criteria) this;
280 | }
281 |
282 | public Criteria andUnitTimeNotBetween(Integer value1, Integer value2) {
283 | addCriterion("unitTime not between", value1, value2, "unitTime");
284 | return (Criteria) this;
285 | }
286 |
287 | public Criteria andUnitNumIsNull() {
288 | addCriterion("unitNum is null");
289 | return (Criteria) this;
290 | }
291 |
292 | public Criteria andUnitNumIsNotNull() {
293 | addCriterion("unitNum is not null");
294 | return (Criteria) this;
295 | }
296 |
297 | public Criteria andUnitNumEqualTo(Integer value) {
298 | addCriterion("unitNum =", value, "unitNum");
299 | return (Criteria) this;
300 | }
301 |
302 | public Criteria andUnitNumNotEqualTo(Integer value) {
303 | addCriterion("unitNum <>", value, "unitNum");
304 | return (Criteria) this;
305 | }
306 |
307 | public Criteria andUnitNumGreaterThan(Integer value) {
308 | addCriterion("unitNum >", value, "unitNum");
309 | return (Criteria) this;
310 | }
311 |
312 | public Criteria andUnitNumGreaterThanOrEqualTo(Integer value) {
313 | addCriterion("unitNum >=", value, "unitNum");
314 | return (Criteria) this;
315 | }
316 |
317 | public Criteria andUnitNumLessThan(Integer value) {
318 | addCriterion("unitNum <", value, "unitNum");
319 | return (Criteria) this;
320 | }
321 |
322 | public Criteria andUnitNumLessThanOrEqualTo(Integer value) {
323 | addCriterion("unitNum <=", value, "unitNum");
324 | return (Criteria) this;
325 | }
326 |
327 | public Criteria andUnitNumIn(List values) {
328 | addCriterion("unitNum in", values, "unitNum");
329 | return (Criteria) this;
330 | }
331 |
332 | public Criteria andUnitNumNotIn(List values) {
333 | addCriterion("unitNum not in", values, "unitNum");
334 | return (Criteria) this;
335 | }
336 |
337 | public Criteria andUnitNumBetween(Integer value1, Integer value2) {
338 | addCriterion("unitNum between", value1, value2, "unitNum");
339 | return (Criteria) this;
340 | }
341 |
342 | public Criteria andUnitNumNotBetween(Integer value1, Integer value2) {
343 | addCriterion("unitNum not between", value1, value2, "unitNum");
344 | return (Criteria) this;
345 | }
346 | }
347 |
348 | public static class Criteria extends GeneratedCriteria {
349 |
350 | protected Criteria() {
351 | super();
352 | }
353 | }
354 |
355 | public static class Criterion {
356 | private String condition;
357 |
358 | private Object value;
359 |
360 | private Object secondValue;
361 |
362 | private boolean noValue;
363 |
364 | private boolean singleValue;
365 |
366 | private boolean betweenValue;
367 |
368 | private boolean listValue;
369 |
370 | private String typeHandler;
371 |
372 | public String getCondition() {
373 | return condition;
374 | }
375 |
376 | public Object getValue() {
377 | return value;
378 | }
379 |
380 | public Object getSecondValue() {
381 | return secondValue;
382 | }
383 |
384 | public boolean isNoValue() {
385 | return noValue;
386 | }
387 |
388 | public boolean isSingleValue() {
389 | return singleValue;
390 | }
391 |
392 | public boolean isBetweenValue() {
393 | return betweenValue;
394 | }
395 |
396 | public boolean isListValue() {
397 | return listValue;
398 | }
399 |
400 | public String getTypeHandler() {
401 | return typeHandler;
402 | }
403 |
404 | protected Criterion(String condition) {
405 | super();
406 | this.condition = condition;
407 | this.typeHandler = null;
408 | this.noValue = true;
409 | }
410 |
411 | protected Criterion(String condition, Object value, String typeHandler) {
412 | super();
413 | this.condition = condition;
414 | this.value = value;
415 | this.typeHandler = typeHandler;
416 | if (value instanceof List>) {
417 | this.listValue = true;
418 | } else {
419 | this.singleValue = true;
420 | }
421 | }
422 |
423 | protected Criterion(String condition, Object value) {
424 | this(condition, value, null);
425 | }
426 |
427 | protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
428 | super();
429 | this.condition = condition;
430 | this.value = value;
431 | this.secondValue = secondValue;
432 | this.typeHandler = typeHandler;
433 | this.betweenValue = true;
434 | }
435 |
436 | protected Criterion(String condition, Object value, Object secondValue) {
437 | this(condition, value, secondValue, null);
438 | }
439 | }
440 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/mapper/InterfaceLimitMapper.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.mapper;
2 |
3 | import com.lovnx.entity.InterfaceLimit;
4 | import com.lovnx.entity.InterfaceLimitExample;
5 | import java.util.List;
6 | import org.apache.ibatis.annotations.Param;
7 |
8 | public interface InterfaceLimitMapper {
9 | int countByExample(InterfaceLimitExample example);
10 |
11 | int deleteByExample(InterfaceLimitExample example);
12 |
13 | int deleteByPrimaryKey(Integer id);
14 |
15 | int insert(InterfaceLimit record);
16 |
17 | int insertSelective(InterfaceLimit record);
18 |
19 | List selectByExample(InterfaceLimitExample example);
20 |
21 | InterfaceLimit selectByPrimaryKey(Integer id);
22 |
23 | int updateByExampleSelective(@Param("record") InterfaceLimit record, @Param("example") InterfaceLimitExample example);
24 |
25 | int updateByExample(@Param("record") InterfaceLimit record, @Param("example") InterfaceLimitExample example);
26 |
27 | int updateByPrimaryKeySelective(InterfaceLimit record);
28 |
29 | int updateByPrimaryKey(InterfaceLimit record);
30 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/service/InterfaceLimitService.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.service;
2 |
3 | import com.lovnx.entity.InterfaceLimit;
4 |
5 | public interface InterfaceLimitService {
6 |
7 | InterfaceLimit getEntityByPri(Integer id);
8 | }
9 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/service/impl/InterfaceLimitServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.service.impl;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 |
6 | import com.lovnx.entity.InterfaceLimit;
7 | import com.lovnx.mapper.InterfaceLimitMapper;
8 | import com.lovnx.service.InterfaceLimitService;
9 |
10 | @Service
11 | public class InterfaceLimitServiceImpl implements InterfaceLimitService {
12 |
13 | @Autowired
14 | private InterfaceLimitMapper mapper;
15 |
16 | @Override
17 | public InterfaceLimit getEntityByPri(Integer id) {
18 | return mapper.selectByPrimaryKey(id);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/test/ApiCallDemo.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.test;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.TimeUnit;
6 | import com.google.common.util.concurrent.RateLimiter;
7 |
8 | public class ApiCallDemo {
9 |
10 | private int permitsPerSecond = 1; //每秒1个许可
11 | private int threadNum = 10;
12 |
13 | public static void main(String[] args) {
14 |
15 | new ApiCallDemo().call();
16 | }
17 |
18 | private void call() {
19 | ExecutorService executor = Executors.newFixedThreadPool(threadNum);
20 |
21 | final RateLimiter rateLimiter = RateLimiter.create(permitsPerSecond);
22 |
23 | for (int i=0; i listenableFuture = executorService.submit(new Task("is " + i));
36 | }
37 |
38 | }
39 |
40 | public static void testListenableFuture() {
41 |
42 | ListeningExecutorService executorService = MoreExecutors
43 | .listeningDecorator(Executors.newCachedThreadPool());
44 |
45 | final ListenableFuture listenableFuture = executorService
46 | .submit(new Task("testListenableFuture"));
47 |
48 | // 同步获取调用结果
49 | try {
50 | System.out.println(listenableFuture.get());
51 | } catch (InterruptedException e1) {
52 | e1.printStackTrace();
53 | } catch (ExecutionException e1) {
54 | e1.printStackTrace();
55 | }
56 |
57 | // 第一种方式
58 | listenableFuture.addListener(new Runnable() {
59 | @Override
60 | public void run() {
61 | try {
62 | System.out.println("get listenable future's result " + listenableFuture.get());
63 | } catch (InterruptedException e) {
64 | e.printStackTrace();
65 | } catch (ExecutionException e) {
66 | e.printStackTrace();
67 |
68 | }
69 | }
70 | }, executorService);
71 |
72 | // 第二种方式
73 | Futures.addCallback(listenableFuture, new FutureCallback() {
74 |
75 | @Override
76 | public void onSuccess(Integer result) {
77 | System.out.println("get listenable future's result with callback " + result);
78 | }
79 |
80 | @Override
81 | public void onFailure(Throwable t) {
82 | t.printStackTrace();
83 | }
84 | });
85 | }
86 | }
87 |
88 | class Task implements Callable {
89 |
90 | String str;
91 |
92 | public Task(String str) {
93 | this.str = str;
94 | }
95 |
96 | @Override
97 | public Integer call() throws Exception {
98 | System.out.println("call execute.." + str);
99 | TimeUnit.SECONDS.sleep(1);
100 | return 7;
101 | }
102 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/test/mytst.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.test;
2 |
3 | import java.util.Timer;
4 | import java.util.TimerTask;
5 | import java.util.concurrent.ExecutorService;
6 | import java.util.concurrent.Executors;
7 | import java.util.concurrent.atomic.AtomicInteger;
8 |
9 | public class mytst {
10 | //单位时间内的调用次数
11 | private int flag = 10;
12 | //线程数量
13 | private int threadNum = 10;
14 | //单位时间1000ms * 60 = 1min
15 | private int timeRound = 1000*60;
16 | //用来标记调用次数
17 | private AtomicInteger num = new AtomicInteger(0);
18 |
19 | public static void main(String[] args) {
20 |
21 | new mytst().call();
22 | }
23 |
24 | private void call() {
25 | ExecutorService executor = Executors.newFixedThreadPool(threadNum);
26 |
27 | Timer timer = new Timer();
28 | timer.schedule(new TimerTask(){
29 | @Override
30 | public void run() {
31 | num.set(0);;
32 | }
33 | }, 0, timeRound);
34 |
35 | for (int i = 0; i < 1000; i++) {
36 | executor.execute(new Runnable() {
37 |
38 | @Override
39 | public void run() {
40 | try {
41 | Thread.sleep(10000);
42 | } catch (InterruptedException e) {
43 | e.printStackTrace();
44 | }
45 | System.out.println(Thread.currentThread().getName()+" 进来了!");
46 | num.incrementAndGet();
47 | if (num.get() <= flag) {
48 | System.out.println(Thread.currentThread().getName()+" 执行任务!");
49 | } else {
50 | System.out.println(Thread.currentThread().getName()+" 执行任务失败!调用超限!");
51 | }
52 | }
53 | });
54 | }
55 |
56 | executor.shutdown();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/web/ComputeController.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | import org.apache.log4j.Logger;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.cloud.client.ServiceInstance;
8 | import org.springframework.cloud.client.discovery.DiscoveryClient;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RequestParam;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import com.lovnx.entity.InterfaceLimit;
15 | import com.lovnx.service.InterfaceLimitService;
16 |
17 | import redis.clients.jedis.Jedis;
18 |
19 | @RestController
20 | public class ComputeController {
21 |
22 | private final Logger logger = Logger.getLogger(getClass());
23 |
24 | @Autowired
25 | private InterfaceLimitService service;
26 |
27 | //单位时间内的调用次数
28 | private int flag = 10;
29 | //单位时间1000ms * 60 = 1min
30 | private static int timeRound = 1000*60;
31 | //用来标记调用次数
32 | private static AtomicLong num = new AtomicLong(0);
33 |
34 | @Autowired
35 | private DiscoveryClient client;
36 |
37 | // static{
38 | // Timer timer = new Timer();
39 | // timer.schedule(new TimerTask(){
40 | // @Override
41 | // public void run() {
42 | // num.set(0);;
43 | // }
44 | // }, 0, timeRound);
45 | // }
46 |
47 | @RequestMapping(value = "/add" ,method = RequestMethod.GET)
48 | public String add(@RequestParam Integer a, @RequestParam Integer b) {
49 |
50 | // num.incrementAndGet();
51 | //
52 | // if (num.get() <= flag) {
53 | // ServiceInstance instance = client.getLocalServiceInstance();
54 | // Integer r = a + b;
55 | // logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
56 | // return "From Service-B, Result is " + r+"\nPort:"+instance.getPort();
57 | // }
58 | // return "调用次数超限,一分钟内最多只能调用10次!";
59 | InterfaceLimit limit = service.getEntityByPri(1);
60 | Jedis jedis = RedisUtils.getJedis();
61 |
62 | //redis存的超时时间
63 | String timeRound_1 = jedis.get("timeRound_1");
64 | //如果不存在或者是不等于数据库设置值
65 | if (timeRound_1 == null || !limit.getUnitTime().toString().equals(timeRound_1)) {
66 | //重新设置超时时间
67 | jedis.set("timeRound_1", limit.getUnitTime().toString());
68 | jedis.expire("num_1", limit.getUnitTime());
69 | }
70 | String num_1 = jedis.get("num_1");
71 | if (num_1 == null) {
72 | jedis.set("num_1", String.valueOf(0));
73 | jedis.expire("num_1", limit.getUnitTime());
74 | }
75 |
76 | jedis.incr("num_1");
77 |
78 | if (Integer.parseInt(jedis.get("num_1")) <= limit.getUnitNum()) {
79 | ServiceInstance instance = client.getLocalServiceInstance();
80 | Integer r = a + b;
81 | logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
82 | return "From Service-B, Result is " + r+"\nPort:"+instance.getPort();
83 | }
84 | return "调用次数超限!";
85 | }
86 |
87 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/web/RateLimiter.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.atomic.AtomicInteger;
5 | import java.util.concurrent.atomic.AtomicLong;
6 |
7 | /**
8 | * @Class RateLimiter 实现基于令牌桶算法,有两个参数:
9 | *
10 | * @para burstSize - 允许作为突发事件进入系统的最大请求数
11 | * @para averageRate - 预期的每秒请求数(ratelimiters使用分钟也支持)
12 | *
13 | * @author yezhiyuan
14 | */
15 | public class RateLimiter {
16 | //限流时间单位
17 | private final long rateToMsConversion;
18 | //当前可供消费的令牌数量
19 | private final AtomicInteger consumedTokens = new AtomicInteger();
20 | //上一次填充令牌的时间戳
21 | private final AtomicLong lastRefillTime = new AtomicLong(0);
22 |
23 | //限流时间单位可设置为TimeUnit.SECONDS,已废弃
24 | @Deprecated
25 | public RateLimiter() {
26 | this(TimeUnit.SECONDS);
27 | }
28 |
29 | //限流时间单位可设置为TimeUnit.SECONDS或TimeUnit.MINUTES
30 | public RateLimiter(TimeUnit averageRateUnit) {
31 | switch (averageRateUnit) {
32 | case SECONDS:
33 | rateToMsConversion = 1000;
34 | break;
35 | case MINUTES:
36 | rateToMsConversion = 60 * 1000;
37 | break;
38 | default:
39 | throw new IllegalArgumentException("TimeUnit of " + averageRateUnit + " is not supported");
40 | }
41 | }
42 |
43 | //这个方法默认传的当前系统时间戳
44 | public boolean acquire(int burstSize, long averageRate) {
45 | return acquire(burstSize, averageRate, System.currentTimeMillis());
46 | }
47 |
48 | public boolean acquire(int burstSize, long averageRate, long currentTimeMillis) {
49 | //这里为了避免傻白甜将burstSize和averageRate设为负值而抛出异常
50 | if (burstSize <= 0 || averageRate <= 0) {
51 | return true;
52 | }
53 | //填充令牌
54 | refillToken(burstSize, averageRate, currentTimeMillis);
55 | //消费令牌成功与否
56 | return consumeToken(burstSize);
57 | }
58 |
59 | private void refillToken(int burstSize, long averageRate, long currentTimeMillis) {
60 | //得到上一次填充令牌的时间戳
61 | long refillTime = lastRefillTime.get();
62 | //时间间隔timeDelta = 传进来的时间戳currentTimeMillis - 上一次填充令牌的时间戳refillTime
63 | long timeDelta = currentTimeMillis - refillTime;
64 | //计算出新的令牌数量newTokens = 时间间隔 * 平均速率 / 限流时间单位
65 | long newTokens = timeDelta * averageRate / rateToMsConversion;
66 | //如果新的令牌数量大于0个
67 | if (newTokens > 0) {
68 | //设置新的填充令牌时间戳newRefillTime,如果上一次填充令牌的时间戳==0就取传进来的currentTimeMillis,如果!=0,
69 | //就等于上一次填充令牌的时间戳 + 新的令牌数量 * 限流时间单位 / 平均速率
70 | long newRefillTime = refillTime == 0
71 | ? currentTimeMillis
72 | : refillTime + newTokens * rateToMsConversion / averageRate;
73 | //如果lastRefillTime内存偏移量值==上一次填充令牌的时间戳refillTime,则将lastRefillTime内存值设置为新的填充令牌时间戳newRefillTime
74 | //成功时进入条件体放令牌
75 | if (lastRefillTime.compareAndSet(refillTime, newRefillTime)) {
76 | //放令牌(核心代码)
77 | while (true) {
78 | //得到当前已消费的令牌数量currentLevel
79 | int currentLevel = consumedTokens.get();
80 | //获取校正令牌数量adjustedLevel,从当前已消费的令牌数量currentLevel和允许最大请求数burstSize间取小者,以防允许最大请求数burstSize变小
81 | //这一步和下一步叫做“流量削峰”
82 | int adjustedLevel = Math.min(currentLevel, burstSize);
83 | //获取新的令牌数量newLevel,0 与 (校正值 - 计算值)之间取大者
84 | int newLevel = (int) Math.max(0, adjustedLevel - newTokens);
85 | //如果当前已消费的令牌内存偏移量等于consumedTokens等于currentLevel,则将已消费的令牌量consumedTokens设置为新的令牌数量newLevel
86 | //终止放令牌,在已消费偏移量不等于currentLevel时循环计算,直到它们相等
87 | if (consumedTokens.compareAndSet(currentLevel, newLevel)) {
88 | return;
89 | }
90 | }
91 | }
92 | }
93 | }
94 |
95 | //消费令牌,传入突发量
96 | private boolean consumeToken(int burstSize) {
97 | //取令牌
98 | while (true) {
99 | //得到当前已消费的令牌数量currentLevel
100 | int currentLevel = consumedTokens.get();
101 | //如果已消费令牌量大于等于突发量,则不能消费令牌
102 | if (currentLevel >= burstSize) {
103 | return false;
104 | }
105 | //消费令牌,已消费令牌量+1
106 | if (consumedTokens.compareAndSet(currentLevel, currentLevel + 1)) {
107 | return true;
108 | }
109 | }
110 | }
111 |
112 | //重置令牌桶
113 | public void reset() {
114 | consumedTokens.set(0);
115 | lastRefillTime.set(0);
116 | }
117 | }
--------------------------------------------------------------------------------
/service-B/src/main/java/com/lovnx/web/RedisUtils.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.stereotype.Component;
6 |
7 | import redis.clients.jedis.Jedis;
8 | import redis.clients.jedis.JedisPool;
9 | import redis.clients.jedis.JedisPoolConfig;
10 |
11 | import java.io.InputStream;
12 | import java.util.Properties;
13 | import java.util.concurrent.locks.ReentrantLock;
14 |
15 | public class RedisUtils {
16 |
17 | private static ReentrantLock lockPool = new ReentrantLock();
18 |
19 | private static final Logger LOGGER = LoggerFactory.getLogger(RedisUtils.class);
20 |
21 | /** Jedis连接池 */
22 | private static JedisPool jedisPool = null;
23 |
24 | /** Redis服务器IP */
25 | private static String host="172.16.16.72";
26 | /** Redis的端口号 */
27 | private static int port=6379;
28 | /** 访问密码 */
29 | private static String password="lemonkz9*l";
30 | /** 超时时间 */
31 | private static int timeout=10000;
32 | /**
33 | * 可用连接实例的最大数目,默认值为8
34 | * 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
35 | */
36 | private static int maxTotal = 1024;
37 | /** 控制一个pool最多有多少个状态为idle(空闲的)的Jedis实例,默认值为8 */
38 | private static int maxIdle = 200;
39 | /**
40 | * 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时
41 | * 如果超过等待时间,则直接抛出JedisConnectionException
42 | */
43 | private static int maxWaitMillis = 10000;
44 | /**
45 | * 在borrow一个Jedis实例时,是否提前进行Validate操作
46 | * 如果为true,则得到的Jedis实例均是可用的
47 | */
48 | private static boolean testOnBorrow = false;
49 |
50 | static {
51 | try {
52 | // String redisPropertiesPath = new StringBuffer("classpath:/redis.properties").toString();
53 | //
54 | // InputStream redisIS = RedisUtils.class.getClassLoader().getResourceAsStream(redisPropertiesPath);
55 | // Properties redisProperties = new Properties();
56 | // redisProperties.load(redisIS);
57 | // host = redisProperties.getProperty("redis.host");
58 | // port = Integer.parseInt(redisProperties.getProperty("redis.port"));
59 | // password = redisProperties.getProperty("redis.password");
60 | //
61 | // maxTotal = Integer.parseInt(redisProperties.getProperty("redis.maxTotal"));
62 | // maxIdle = Integer.parseInt(redisProperties.getProperty("redis.maxIdle"));
63 | // timeout = Integer.parseInt(redisProperties.getProperty("redis.timeout"));
64 | // maxWaitMillis = Integer.parseInt(redisProperties.getProperty("redis.maxWaitMillis"));
65 | // testOnBorrow = Boolean.parseBoolean(redisProperties.getProperty("redis.testOnBorrow"));
66 | LOGGER.info("初始化Redis配置参数成功.");
67 | } catch (Exception ex) {
68 | LOGGER.error("初始化Redis配置参数失败.", ex);
69 | }
70 | initialPool();
71 | setShutdownWork();
72 | }
73 |
74 | private RedisUtils() {
75 | throw new RuntimeException("禁止实例化Redis访问工具类.");
76 | }
77 |
78 | /**
79 | * 初始化Redis连接池
80 | */
81 | private static void initialPool(){
82 | lockPool.lock();
83 | try {
84 | if(jedisPool == null) {
85 | JedisPoolConfig config = new JedisPoolConfig();
86 | config.setMaxTotal(maxTotal);
87 | config.setMaxIdle(maxIdle);
88 | config.setMaxWaitMillis(maxWaitMillis);
89 | config.setTestOnBorrow(testOnBorrow);
90 | jedisPool = new JedisPool(config, host, port, timeout, password);
91 | LOGGER.info("创建Redis Pool成功.");
92 | }
93 | } catch (Exception ex) {
94 | LOGGER.error("创建Redis Pool失败.", ex);
95 | } finally {
96 | lockPool.unlock();
97 | }
98 | }
99 |
100 | /**
101 | * 设置系统停止时需执行的任务
102 | */
103 | private static void setShutdownWork() {
104 | try{
105 | Runtime runtime = Runtime.getRuntime();
106 | runtime.addShutdownHook(new Thread(){
107 | @Override
108 | public void run() {
109 | try {
110 | if(jedisPool != null) {
111 | jedisPool.destroy();
112 | jedisPool = null;
113 | LOGGER.info("关闭Redis Pool成功.");
114 | }
115 | } catch (Exception ex) {
116 | LOGGER.error("关闭Redis Pool失败.", ex);
117 | }
118 | }
119 | });
120 | LOGGER.info("设置系统停止时关闭Redis Pool的任务成功.");
121 | } catch (Exception ex) {
122 | LOGGER.error("设置系统停止时关闭Redis Pool的任务失败.");
123 | }
124 | }
125 |
126 | /**
127 | * 从连接池中获取Jedis实例
128 | * @return Jedis Jedis实例
129 | */
130 | public static Jedis getJedis() {
131 | if (jedisPool == null) {
132 | initialPool();
133 | }
134 | Jedis jedis = null;
135 | try {
136 | jedis = jedisPool.getResource();
137 | } catch (Exception ex) {
138 | LOGGER.error("获取Jedis失败.", ex);
139 | }
140 | return jedis;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/service-B/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=service-B
2 | server.port=7075
3 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
4 |
5 | mysqldb.datasource.url=jdbc:mysql://localhost:3306/sso?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull
6 | mysqldb.datasource.username=
7 | mysqldb.datasource.password=
8 | mysqldb.datasource.driverClassName=com.mysql.jdbc.Driver
9 | mysqldb.datasource.initialSize=1
10 | mysqldb.datasource.minIdle=1
11 | mysqldb.datasource.maxIdle=5
12 | mysqldb.datasource.maxActive=50
13 | mysqldb.datasource.maxWait=10000
14 | mysqldb.datasource.timeBetweenEvictionRunsMillis=10000
15 | mysqldb.datasource.minEvictableIdleTimeMillis=300000
16 | mysqldb.datasource.validationQuery=select 'x'
17 | mysqldb.datasource.testWhileIdle=true
18 | mysqldb.datasource.testOnBorrow=false
19 | mysqldb.datasource.testOnReturn=false
20 | mysqldb.datasource.poolPreparedStatements=true
21 | mysqldb.datasource.maxOpenPreparedStatements=20
22 | mysqldb.datasource.filters=stat
23 |
24 | mysqldb.datasource.mapperLocations=classpath:mapper/*.xml
25 | mysqldb.datasource.typeAliasPackage=com.lovnx.entity
26 |
27 | #pagehelper
28 | pagehelper.helperDialect=mysql
29 | pagehelper.reasonable=false
30 | pagehelper.supportMethodsArguments=true
31 | pagehelper.params=count=countSql
32 |
33 | #when SpringBoot occurs 404 ,throw a Exception directly
34 | spring.mvc.throw-exception-if-no-handler-found=true
35 | #Whether to open the default resource processing, the default is true
36 | spring.resources.add-mappings=false
--------------------------------------------------------------------------------
/service-B/src/main/resources/mapper/InterfaceLimitMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | and ${criterion.condition}
19 |
20 |
21 | and ${criterion.condition} #{criterion.value}
22 |
23 |
24 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
25 |
26 |
27 | and ${criterion.condition}
28 |
29 | #{listItem}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | and ${criterion.condition}
48 |
49 |
50 | and ${criterion.condition} #{criterion.value}
51 |
52 |
53 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
54 |
55 |
56 | and ${criterion.condition}
57 |
58 | #{listItem}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | id, interfaceId, unitTime, unitNum
70 |
71 |
72 | select
73 |
74 | distinct
75 |
76 |
77 | from interface_limit
78 |
79 |
80 |
81 |
82 | order by ${orderByClause}
83 |
84 |
85 |
86 | select
87 |
88 | from interface_limit
89 | where id = #{id,jdbcType=INTEGER}
90 |
91 |
92 | delete from interface_limit
93 | where id = #{id,jdbcType=INTEGER}
94 |
95 |
96 | delete from interface_limit
97 |
98 |
99 |
100 |
101 |
102 | insert into interface_limit (id, interfaceId, unitTime,
103 | unitNum)
104 | values (#{id,jdbcType=INTEGER}, #{interfaceId,jdbcType=INTEGER}, #{unitTime,jdbcType=INTEGER},
105 | #{unitNum,jdbcType=INTEGER})
106 |
107 |
108 | insert into interface_limit
109 |
110 |
111 | id,
112 |
113 |
114 | interfaceId,
115 |
116 |
117 | unitTime,
118 |
119 |
120 | unitNum,
121 |
122 |
123 |
124 |
125 | #{id,jdbcType=INTEGER},
126 |
127 |
128 | #{interfaceId,jdbcType=INTEGER},
129 |
130 |
131 | #{unitTime,jdbcType=INTEGER},
132 |
133 |
134 | #{unitNum,jdbcType=INTEGER},
135 |
136 |
137 |
138 |
139 | select count(*) from interface_limit
140 |
141 |
142 |
143 |
144 |
145 | update interface_limit
146 |
147 |
148 | id = #{record.id,jdbcType=INTEGER},
149 |
150 |
151 | interfaceId = #{record.interfaceId,jdbcType=INTEGER},
152 |
153 |
154 | unitTime = #{record.unitTime,jdbcType=INTEGER},
155 |
156 |
157 | unitNum = #{record.unitNum,jdbcType=INTEGER},
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | update interface_limit
166 | set id = #{record.id,jdbcType=INTEGER},
167 | interfaceId = #{record.interfaceId,jdbcType=INTEGER},
168 | unitTime = #{record.unitTime,jdbcType=INTEGER},
169 | unitNum = #{record.unitNum,jdbcType=INTEGER}
170 |
171 |
172 |
173 |
174 |
175 | update interface_limit
176 |
177 |
178 | interfaceId = #{interfaceId,jdbcType=INTEGER},
179 |
180 |
181 | unitTime = #{unitTime,jdbcType=INTEGER},
182 |
183 |
184 | unitNum = #{unitNum,jdbcType=INTEGER},
185 |
186 |
187 | where id = #{id,jdbcType=INTEGER}
188 |
189 |
190 | update interface_limit
191 | set interfaceId = #{interfaceId,jdbcType=INTEGER},
192 | unitTime = #{unitTime,jdbcType=INTEGER},
193 | unitNum = #{unitNum,jdbcType=INTEGER}
194 | where id = #{id,jdbcType=INTEGER}
195 |
196 |
--------------------------------------------------------------------------------
/service-B2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | service-B2
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | org.springframework.cloud
19 | spring-cloud-starter-eureka
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-actuator
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-test
28 | test
29 |
30 |
31 | org.jolokia
32 | jolokia-core
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-web
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-zipkin
41 |
42 |
43 |
44 |
45 |
46 |
47 | org.springframework.cloud
48 | spring-cloud-dependencies
49 | Camden.SR5
50 | pom
51 | import
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-maven-plugin
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/service-B2/src/main/java/com/lovnx/B2_Application.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @EnableDiscoveryClient
8 | @SpringBootApplication
9 | public class B2_Application {
10 |
11 | public static void main(String[] args) {
12 | new SpringApplicationBuilder(B2_Application.class).web(true).run(args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/service-B2/src/main/java/com/lovnx/web/ComputeController.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.web;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 |
5 | import org.apache.log4j.Logger;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.cloud.client.ServiceInstance;
8 | import org.springframework.cloud.client.discovery.DiscoveryClient;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RequestParam;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import org.springframework.web.client.RestTemplate;
14 |
15 | @RestController
16 | public class ComputeController {
17 |
18 | private final Logger logger = Logger.getLogger(getClass());
19 |
20 | @Autowired
21 | private DiscoveryClient client;
22 |
23 | @RequestMapping(value = "/**" ,method = RequestMethod.GET)
24 | public String add(@RequestParam Integer a, @RequestParam Integer b,HttpServletRequest request) {
25 | System.out.println(request.getRequestURL());
26 | ServiceInstance instance = client.getLocalServiceInstance();
27 | Integer r = a + b;
28 | logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
29 | return "From Service-B, Result is " + r+"\nPort:"+instance.getPort();
30 | }
31 |
32 | //B服务调用A服务
33 | @RequestMapping(value="testServiceA",method=RequestMethod.GET)
34 | public String testServiceB(@RequestParam Integer a,@RequestParam Integer b){
35 | RestTemplate restTemplate=new RestTemplate();
36 | return restTemplate.getForObject("http://localhost:7074/add?a="+a+"&b="+b, String.class);
37 | }
38 | }
--------------------------------------------------------------------------------
/service-B2/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=service-B
2 | server.port=7076
3 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
4 | management.security.enabled=false
5 | spring.zipkin.base-url=http://localhost:7082
--------------------------------------------------------------------------------
/service-B2/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/service-admin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | service-admin
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | org.springframework.cloud
19 | spring-cloud-starter-eureka
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-actuator
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-starter-eureka
28 |
29 |
30 | de.codecentric
31 | spring-boot-admin-server
32 | 1.4.6
33 |
34 |
35 | de.codecentric
36 | spring-boot-admin-server-ui
37 | 1.4.6
38 |
39 |
40 | org.jolokia
41 | jolokia-core
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-mail
46 |
47 |
48 |
49 |
50 |
51 |
52 | org.springframework.cloud
53 | spring-cloud-dependencies
54 | Camden.SR5
55 | pom
56 | import
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-maven-plugin
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/service-admin/src/main/java/com/lovnx/NotifierConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.scheduling.annotation.EnableScheduling;
7 |
8 | import com.netflix.governator.annotations.binding.Primary;
9 |
10 | import de.codecentric.boot.admin.notify.Notifier;
11 | import de.codecentric.boot.admin.notify.RemindingNotifier;
12 |
13 | /**
14 | *
15 | * @Title: 为监控的服务添加邮件通知
16 | * @Package com.lovnx
17 | * @author yezhiyuan
18 | * @date 2017年6月14日 上午10:18:13
19 | * @version V1.0
20 | */
21 |
22 | @Configuration
23 | @EnableScheduling
24 | public class NotifierConfiguration {
25 |
26 | @Autowired
27 | private Notifier notifier;
28 |
29 | //服务上线或者下线都通知
30 | private String[] reminderStatuses = { "DOWN" };
31 |
32 | @Bean
33 | @Primary
34 | public RemindingNotifier remindingNotifier() {
35 | RemindingNotifier remindingNotifier = new RemindingNotifier(notifier);
36 | //设定时间,5分钟提醒一次
37 | // remindingNotifier.setReminderPeriod(TimeUnit.MINUTES.toMillis(5));
38 | //设定监控服务状态,状态改变为给定值的时候提醒
39 | remindingNotifier.setReminderStatuses(reminderStatuses);
40 | return remindingNotifier;
41 | }
42 |
43 | // @Scheduled(fixedRate = 60_000L)
44 | // public void remind() {
45 | // remindingNotifier().sendReminders();
46 | // }
47 | }
--------------------------------------------------------------------------------
/service-admin/src/main/java/com/lovnx/SpringBootAdminApplication.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | import de.codecentric.boot.admin.config.EnableAdminServer;
9 |
10 | @Configuration
11 | @EnableAutoConfiguration
12 | @EnableDiscoveryClient
13 | @EnableAdminServer
14 | public class SpringBootAdminApplication {
15 | public static void main(String[] args) {
16 | SpringApplication.run(SpringBootAdminApplication.class, args);
17 | }
18 | }
--------------------------------------------------------------------------------
/service-admin/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=7088
2 | spring.application.name=service-admin
3 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
4 | management.security.enabled=false
5 | #endpoints.health.sensitive=true
6 | #eureka.instance.leaseRenewalIntervalInSeconds=5
7 | info.version=@project.version@
8 |
9 | spring.mail.host=smtp.qq.com
10 | spring.boot.admin.notify.mail.to=930999349@qq.com
11 | #spring.boot.admin.notify.mail.subject=
12 | #spring.boot.admin.notify.mail.from=
--------------------------------------------------------------------------------
/service-admin/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/sleuth/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.lovnx
7 | micro-service
8 | 0.0.1-SNAPSHOT
9 |
10 | com.lovnx
11 | sleuth
12 | 0.0.1-SNAPSHOT
13 | sleuth
14 | http://maven.apache.org
15 |
16 |
17 | UTF-8
18 | 1.7
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 | io.zipkin.java
37 | zipkin-server
38 |
39 |
40 |
41 | io.zipkin.java
42 | zipkin-autoconfigure-ui
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.cloud
50 | spring-cloud-dependencies
51 | Camden.SR5
52 | pom
53 | import
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/sleuth/src/main/java/com/lovnx/Sleuth_Application.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | import zipkin.server.EnableZipkinServer;
7 |
8 | @SpringBootApplication
9 | @EnableZipkinServer
10 | public class Sleuth_Application {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(Sleuth_Application.class, args);
14 | }
15 | }
--------------------------------------------------------------------------------
/sleuth/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #spring.application.name=service-B
2 | server.port=7082
3 | #eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
--------------------------------------------------------------------------------
/sleuth/src/test/java/org/sleuth/AppTest.java:
--------------------------------------------------------------------------------
1 | package org.sleuth;
2 |
3 | import junit.framework.Test;
4 | import junit.framework.TestCase;
5 | import junit.framework.TestSuite;
6 |
7 | /**
8 | * Unit test for simple App.
9 | */
10 | public class AppTest
11 | extends TestCase
12 | {
13 | /**
14 | * Create the test case
15 | *
16 | * @param testName name of the test case
17 | */
18 | public AppTest( String testName )
19 | {
20 | super( testName );
21 | }
22 |
23 | /**
24 | * @return the suite of tests being tested
25 | */
26 | public static Test suite()
27 | {
28 | return new TestSuite( AppTest.class );
29 | }
30 |
31 | /**
32 | * Rigourous Test :-)
33 | */
34 | public void testApp()
35 | {
36 | assertTrue( true );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/turbine/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | turbine
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 3.8.1
21 | test
22 |
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-turbine
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-netflix-turbine
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-actuator
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.springframework.cloud
45 | spring-cloud-dependencies
46 | Camden.SR5
47 | pom
48 | import
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-maven-plugin
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/turbine/src/main/java/com/turbine/TurbineApplication.java:
--------------------------------------------------------------------------------
1 | package com.turbine;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.netflix.turbine.EnableTurbine;
6 |
7 | @SpringBootApplication
8 | @EnableTurbine
9 | public class TurbineApplication {
10 | public static void main(String[] args) {
11 | new SpringApplicationBuilder(TurbineApplication.class).web(true).run(args);
12 | }
13 | }
--------------------------------------------------------------------------------
/turbine/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application.name: microservice-hystrix-turbine
3 | server:
4 | port: 7081
5 | security.basic.enabled: false
6 | turbine:
7 | aggregator:
8 | clusterConfig: default # 指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问
9 | appConfig: hystrix,feign-hystrix
10 | clusterNameExpression: new String("default")
11 | # 1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称
12 | # 2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default
13 | # 3. 当clusterNameExpression: metadata['cluster']时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC
14 | eureka:
15 | client:
16 | serviceUrl:
17 | defaultZone: http://localhost:7070/eureka/
18 |
19 | #进入hystrixdashboard页面,输入:localhost:7081/turbine.stream
--------------------------------------------------------------------------------
/zuul/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.lovnx
5 | micro-service
6 | 0.0.1-SNAPSHOT
7 |
8 | zuul
9 | jar
10 |
11 |
12 | UTF-8
13 | 1.7
14 |
15 |
16 |
17 |
18 |
19 | org.springframework.cloud
20 | spring-cloud-starter-zuul
21 |
22 |
23 |
24 | org.springframework.cloud
25 | spring-cloud-starter-eureka
26 |
27 |
28 |
29 | com.marcosbarbero.cloud
30 | spring-cloud-zuul-ratelimit
31 | 1.0.7.RELEASE
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-dependencies
41 | Camden.SR5
42 | pom
43 | import
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/zuul/src/main/java/com/lovnx/ZuulApplication.java:
--------------------------------------------------------------------------------
1 | package com.lovnx;
2 |
3 | import org.springframework.boot.builder.SpringApplicationBuilder;
4 | import org.springframework.cloud.client.SpringCloudApplication;
5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
6 | import org.springframework.context.annotation.Bean;
7 |
8 | import com.lovnx.filter.AccessFilter;
9 | import com.lovnx.filter.ErrorFilter;
10 | import com.lovnx.filter.RateLimitFilter;
11 | import com.lovnx.filter.ResultFilter;
12 | import com.lovnx.filter.UuidFilter;
13 | import com.lovnx.filter.ValidateFilter;
14 |
15 | @EnableZuulProxy
16 | @SpringCloudApplication
17 | public class ZuulApplication {
18 |
19 | public static void main(String[] args) {
20 | new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
21 | }
22 |
23 | @Bean
24 | public AccessFilter accessFilter() {
25 | return new AccessFilter();
26 | }
27 |
28 | @Bean
29 | public RateLimitFilter rateLimiterFilter() {
30 | return new RateLimitFilter();
31 | }
32 |
33 | @Bean
34 | public ResultFilter resultFilter() {
35 | return new ResultFilter();
36 | }
37 |
38 | @Bean
39 | public UuidFilter uuidFilter() {
40 | return new UuidFilter();
41 | }
42 |
43 | @Bean
44 | public ValidateFilter validateFilter() {
45 | return new ValidateFilter();
46 | }
47 |
48 | @Bean
49 | public ErrorFilter errorFilter() {
50 | return new ErrorFilter();
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/zuul/src/main/java/com/lovnx/filter/ErrorFilter.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.filter;
2 |
3 | import com.netflix.zuul.ZuulFilter;
4 | import com.netflix.zuul.context.RequestContext;
5 |
6 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
7 |
8 | import org.bouncycastle.jcajce.provider.digest.MD5;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.UUID;
13 |
14 | import javax.servlet.http.HttpServletRequest;
15 | import javax.servlet.http.HttpServletResponse;
16 |
17 | public class ErrorFilter extends ZuulFilter {
18 |
19 | private static Logger log = LoggerFactory.getLogger(ErrorFilter.class);
20 |
21 | @Override
22 | public String filterType() {
23 | return "error";
24 | }
25 |
26 | @Override
27 | public int filterOrder() {
28 | return 0;
29 | }
30 |
31 | @Override
32 | public boolean shouldFilter() {
33 | return true;
34 | }
35 |
36 | @Override
37 | public Object run() {
38 | RequestContext ctx = RequestContext.getCurrentContext();
39 | HttpServletRequest request = ctx.getRequest();
40 | //HttpServletResponse response = ctx.getResponse();
41 |
42 | log.info("进入错误异常的过滤器!");
43 |
44 | log.info("===============");
45 |
46 | // log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
47 | // System.out.println(request.getRequestURL());
48 |
49 | // Object accessToken = request.getParameter("accessToken");
50 | // if(accessToken == null) {
51 | // log.warn("access token is empty");
52 | // ctx.setSendZuulResponse(false);
53 | // ctx.setResponseStatusCode(401);
54 | // return null;
55 | // }
56 | // log.info("access token ok");
57 | return null;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/zuul/src/main/java/com/lovnx/filter/FirstFilter.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.filter;
2 |
3 | import com.netflix.zuul.ZuulFilter;
4 | import com.netflix.zuul.context.RequestContext;
5 |
6 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 |
14 | public class FirstFilter extends ZuulFilter {
15 |
16 | private static Logger log = LoggerFactory.getLogger(FirstFilter.class);
17 |
18 | @Override
19 | public String filterType() {
20 | return "pre";
21 | }
22 |
23 | @Override
24 | public int filterOrder() {
25 | return 0;
26 | }
27 |
28 | @Override
29 | public boolean shouldFilter() {
30 | return true;
31 | }
32 |
33 | @Override
34 | public Object run() {
35 | RequestContext ctx = RequestContext.getCurrentContext();
36 | HttpServletRequest request = ctx.getRequest();
37 | //HttpServletResponse response = ctx.getResponse();
38 |
39 | log.info("第一级过滤器!");
40 |
41 | log.info("===============");
42 |
43 | // log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
44 | // System.out.println(request.getRequestURL());
45 |
46 | // Object accessToken = request.getParameter("accessToken");
47 | // if(accessToken == null) {
48 | // log.warn("access token is empty");
49 | // ctx.setSendZuulResponse(false);
50 | // ctx.setResponseStatusCode(401);
51 | // return null;
52 | // }
53 | // log.info("access token ok");
54 | return null;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/zuul/src/main/java/com/lovnx/filter/ResultFilter.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.filter;
2 |
3 | import com.netflix.zuul.ZuulFilter;
4 | import com.netflix.zuul.context.RequestContext;
5 |
6 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 |
14 | public class ResultFilter extends ZuulFilter {
15 |
16 | private static Logger log = LoggerFactory.getLogger(ResultFilter.class);
17 |
18 | @Override
19 | public String filterType() {
20 | return "post";
21 | }
22 |
23 | @Override
24 | public int filterOrder() {
25 | return 0;
26 | }
27 |
28 | @Override
29 | public boolean shouldFilter() {
30 | return true;
31 | }
32 |
33 | @Override
34 | public Object run() {
35 | RequestContext ctx = RequestContext.getCurrentContext();
36 | HttpServletRequest request = ctx.getRequest();
37 | //HttpServletResponse response = ctx.getResponse();
38 |
39 | log.info("进入结果处理的过滤器!");
40 |
41 | log.info("===============");
42 |
43 | // log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
44 | // System.out.println(request.getRequestURL());
45 |
46 | // Object accessToken = request.getParameter("accessToken");
47 | // if(accessToken == null) {
48 | // log.warn("access token is empty");
49 | // ctx.setSendZuulResponse(false);
50 | // ctx.setResponseStatusCode(401);
51 | // return null;
52 | // }
53 | // log.info("access token ok");
54 | return null;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/zuul/src/main/java/com/lovnx/filter/SecondFilter.java:
--------------------------------------------------------------------------------
1 | package com.lovnx.filter;
2 |
3 | import com.netflix.zuul.ZuulFilter;
4 | import com.netflix.zuul.context.RequestContext;
5 |
6 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 |
14 | public class SecondFilter extends ZuulFilter {
15 |
16 | private static Logger log = LoggerFactory.getLogger(SecondFilter.class);
17 |
18 | @Override
19 | public String filterType() {
20 | return "pre";
21 | }
22 |
23 | @Override
24 | public int filterOrder() {
25 | return 1;
26 | }
27 |
28 | @Override
29 | public boolean shouldFilter() {
30 | return true;
31 | }
32 |
33 | @Override
34 | public Object run() {
35 | RequestContext ctx = RequestContext.getCurrentContext();
36 | HttpServletRequest request = ctx.getRequest();
37 | //HttpServletResponse response = ctx.getResponse();
38 |
39 | log.info("第二级过滤器!");
40 |
41 | log.info("===============");
42 |
43 |
44 | throw new RuntimeException();
45 |
46 |
47 | // log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
48 | // System.out.println(request.getRequestURL());
49 |
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/zuul/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=zuul
2 | server.port=7073
3 |
4 | # routes to serviceId
5 | #zuul.routes.api-a.path=/api-a/**
6 | #zuul.routes.api-a.serviceId=service-A
7 |
8 | zuul.routes.api-b.path=/api-b/**
9 | zuul.routes.api-b.serviceId=ribbon
10 |
11 | zuul.routes.api-b.path=/service-b/**
12 | zuul.routes.api-b.serviceId=service-b
13 |
14 | # routes to url
15 | zuul.routes.api-a-url.path=/api-a-url/**
16 | zuul.routes.api-a-url.url=http://localhost:7074/
17 |
18 | eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
--------------------------------------------------------------------------------