├── 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 | ![image](https://img.shields.io/badge/Spring%20Cloud-%E2%98%85%E2%98%85%E2%98%85-green.svg) 2 | ![image](https://img.shields.io/badge/Netflix-%E2%98%85%E2%98%85%E2%98%85-red.svg) 3 | 4 | spring-cloud 微服务组件demo 5 | === 6 | 7 | ![image](http://img.blog.csdn.net/20171018201759315?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmlja2l5ZWF0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
工程名 描述 端口
eureka-server 服务发现与注册中心 7070
ribbon 负载均衡器 7071
config-server 配置管理中心 7072
zuul 动态路由器 7073
service-A A服务,用来测试服务间调用与路由 7074
service-B B服务,整合Mybatis、PageHelper、Redis,整合接口限速方案,可选google Guava RateLimiter与自实现 7075
service-B2 B2服务,与B服务serviceId相同,用来测试负载均衡和容错 7076
hystrix-ribbon 负载均衡器的容错测试 7077
feign 声明式、模板化的HTTP客户端,可用来做负载均衡,较轻量 7078
hystrix-feign feign的容错测试 7079
hystrix-dashboard hystrix可视化监控台 7080
turbine 集群下hystrix可视化监控台 7081
sleuth 服务链路追踪 7082
service-admin spring boot admin监控台 7088
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 | 85 | 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 | 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/ --------------------------------------------------------------------------------