├── demo-config-info ├── demo-spring-cloud-pro.yml ├── demo-spring-cloud-test.yml └── demo-spring-cloud-dev.yml ├── README.md ├── demo-goods ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── logback-spring.xml │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demogoods │ │ │ ├── model │ │ │ └── User.java │ │ │ ├── config │ │ │ ├── FeignClientLoggerConfiguration.java │ │ │ └── EurekaHttpsClientConfiguration.java │ │ │ ├── controller │ │ │ ├── HystrixAndFeignController.java │ │ │ ├── FeignUploadFileController.java │ │ │ ├── OrderController.java │ │ │ ├── GoodsController.java │ │ │ └── FeignGetInterceptorController.java │ │ │ ├── exception │ │ │ └── GlobalExceptionHandle.java │ │ │ ├── DemoGoodsApplication.java │ │ │ └── feign │ │ │ └── OrderFeign.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demogoods │ │ └── DemoGoodsApplicationTests.java └── pom.xml ├── demo-order ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── logback-spring.xml │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demoorder │ │ │ ├── component │ │ │ ├── ConfigServerInfoProperties.java │ │ │ └── ServiceInfo.java │ │ │ ├── model │ │ │ └── User.java │ │ │ ├── feign │ │ │ ├── hystrix │ │ │ │ └── HystrixAndFeignHystrix.java │ │ │ ├── HystrixAndFeignFeign.java │ │ │ ├── GitHubFeign.java │ │ │ ├── GoodsFeign.java │ │ │ ├── FeignGetInterceptorFeign.java │ │ │ └── FeignUploadFileFeign.java │ │ │ ├── config │ │ │ ├── FeignClientLoggerConfiguration.java │ │ │ ├── FeignUploadFileSupportConfiguration.java │ │ │ ├── FeignClientOkHttpConfiguration.java │ │ │ ├── EurekaHttpsClientConfiguration.java │ │ │ ├── StaticBackupRegistryListConfiguration.java │ │ │ └── AutoRefreshConfigServerConfiguration.java │ │ │ ├── controller │ │ │ ├── HystrixAndFeignController.java │ │ │ ├── GrayController.java │ │ │ ├── ConfigServerInfoController.java │ │ │ ├── RibbonRestTemplateController.java │ │ │ ├── FeignUploadFileController.java │ │ │ ├── HystrixIntroductionController.java │ │ │ ├── GitHubController.java │ │ │ ├── OrderController.java │ │ │ ├── GoodsController.java │ │ │ └── FeignGetInterceptorController.java │ │ │ ├── exception │ │ │ └── GlobalExceptionHandle.java │ │ │ ├── DemoOrderApplication.java │ │ │ └── interceptor │ │ │ └── FeignRequestInterceptor.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demoorder │ │ └── DemoOrderApplicationTests.java └── pom.xml ├── demo-api-zuul ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── logback-spring.xml │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demoapizuul │ │ │ ├── constants │ │ │ └── SessionContants.java │ │ │ ├── controller │ │ │ └── LocalController.java │ │ │ ├── exception │ │ │ └── GlobalExceptionHandle.java │ │ │ ├── DemoApiZuulApplication.java │ │ │ ├── filters │ │ │ ├── PostFirstFilter.java │ │ │ ├── GrayFilter.java │ │ │ ├── PreFirstFilter.java │ │ │ ├── PreSecondFilter.java │ │ │ └── ModifyRequestEntityFilter.java │ │ │ ├── fallback │ │ │ └── ZuulFallback.java │ │ │ └── config │ │ │ ├── EurekaHttpsClientConfiguration.java │ │ │ └── StaticBackupRegistryListConfiguration.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demoapizuul │ │ └── DemoApiZuulApplicationTests.java └── pom.xml ├── demo-admin-server ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── bootstrap.yml │ │ │ └── logback-spring.xml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demoadminserver │ │ │ ├── DemoAdminServerApplication.java │ │ │ └── config │ │ │ └── EurekaHttpsClientConfiguration.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demoadminserver │ │ └── DemoAdminServerApplicationTests.java └── pom.xml ├── demo-config-server ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── logback-spring.xml │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── democonfigserver │ │ │ ├── DemoConfigServerApplication.java │ │ │ └── config │ │ │ ├── SpringSecurityConfiguration.java │ │ │ └── EurekaHttpsClientConfiguration.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── democonfigserver │ │ └── DemoConfigServerApplicationTests.java └── pom.xml ├── demo-eureka-server ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── EurekaServer.p12 │ │ │ ├── logback-spring.xml │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demoeurekaserver │ │ │ ├── DemoEurekaServerApplication.java │ │ │ └── config │ │ │ ├── SpringSecurityConfiguration.java │ │ │ └── EurekaHttpsClientConfiguration.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demoeurekaserver │ │ └── DemoEurekaServerApplicationTests.java └── pom.xml ├── demo-hystrix-dashboard ├── src │ ├── main │ │ ├── resources │ │ │ ├── EurekaClient.p12 │ │ │ ├── bootstrap.yml │ │ │ └── logback-spring.xml │ │ └── java │ │ │ └── com │ │ │ └── lynchj │ │ │ └── demohystrixdashboard │ │ │ ├── DemoHystrixDashboardApplication.java │ │ │ └── config │ │ │ └── EurekaHttpsClientConfiguration.java │ └── test │ │ └── java │ │ └── com │ │ └── lynchj │ │ └── demohystrixdashboard │ │ └── DemoHystrixDashboardApplicationTests.java └── pom.xml └── pom.xml /demo-config-info/demo-spring-cloud-pro.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo-config-info/demo-spring-cloud-test.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 记录笔记使用的 演示样例 Spring Cloud Finchley 2 | -------------------------------------------------------------------------------- /demo-config-info/demo-spring-cloud-dev.yml: -------------------------------------------------------------------------------- 1 | demo: 2 | one: 哈哈0.3 3 | two: 嘿嘿0.2 4 | -------------------------------------------------------------------------------- /demo-goods/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-goods/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-order/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-order/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-api-zuul/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-api-zuul/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-admin-server/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-admin-server/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-config-server/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-config-server/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-eureka-server/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-eureka-server/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-eureka-server/src/main/resources/EurekaServer.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-eureka-server/src/main/resources/EurekaServer.p12 -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/main/resources/EurekaClient.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlowSlicing/demo-spring-cloud-finchley/HEAD/demo-hystrix-dashboard/src/main/resources/EurekaClient.p12 -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/constants/SessionContants.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.constants; 2 | 3 | /** 4 | * @Author:大漠知秋 5 | * @Description:会话相关常量 6 | * @CreateDate:5:10 PM 2018/10/30 7 | */ 8 | public interface SessionContants { 9 | 10 | String LOGIC_IS_SUCCESS = "LOGIC_IS_SUCCESS"; 11 | 12 | String ERROR_RESPONSE_BODY = "{\"status\": 10600, \"msg\":\"%s\"}"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /demo-goods/src/test/java/com/lynchj/demogoods/DemoGoodsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoGoodsApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/component/ConfigServerInfoProperties.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.component; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Data 8 | @Component 9 | @ConfigurationProperties("demo") 10 | public class ConfigServerInfoProperties { 11 | 12 | private String one; 13 | 14 | private String two; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-order/src/test/java/com/lynchj/demoorder/DemoOrderApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoOrderApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-api-zuul/src/test/java/com/lynchj/demoapizuul/DemoApiZuulApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoApiZuulApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-config-server/src/test/java/com/lynchj/democonfigserver/DemoConfigServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.democonfigserver; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoConfigServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-admin-server/src/test/java/com/lynchj/demoadminserver/DemoAdminServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoadminserver; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoAdminServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-eureka-server/src/test/java/com/lynchj/demoeurekaserver/DemoEurekaServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoeurekaserver; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoEurekaServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/test/java/com/lynchj/demohystrixdashboard/DemoHystrixDashboardApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demohystrixdashboard; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoHystrixDashboardApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/model/User.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Data; 5 | import org.springframework.format.annotation.DateTimeFormat; 6 | 7 | import java.util.Date; 8 | 9 | @Data 10 | public class User { 11 | 12 | private String username; 13 | 14 | private Integer age; 15 | 16 | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") 17 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 18 | private Date birthday; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/model/User.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Data; 5 | import org.springframework.format.annotation.DateTimeFormat; 6 | 7 | import java.util.Date; 8 | 9 | @Data 10 | public class User { 11 | 12 | private String username; 13 | 14 | private Integer age; 15 | 16 | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") 17 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 18 | private Date birthday; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/hystrix/HystrixAndFeignHystrix.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign.hystrix; 2 | 3 | import com.lynchj.demoorder.feign.HystrixAndFeignFeign; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * @Author:大漠知秋 8 | * @Description:Hystrix 结合 Feign 案例 9 | * @CreateDate:10:23 AM 2018/10/29 10 | */ 11 | @Component 12 | public class HystrixAndFeignHystrix implements HystrixAndFeignFeign { 13 | 14 | @Override 15 | public String getUser(String username) { 16 | 17 | return "No Hello " + username; 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/config/FeignClientLoggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.config; 2 | 3 | import feign.Logger; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:Feign Client Logger Level Configuration 10 | * @CreateDate:4:53 PM 2018/10/24 11 | */ 12 | @Configuration 13 | public class FeignClientLoggerConfiguration { 14 | 15 | @Bean 16 | Logger.Level FeignClientLoggerLevel() { 17 | return Logger.Level.FULL; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/FeignClientLoggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import feign.Logger; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:Feign Client Logger Level Configuration 10 | * @CreateDate:4:53 PM 2018/10/24 11 | */ 12 | @Configuration 13 | public class FeignClientLoggerConfiguration { 14 | 15 | @Bean 16 | Logger.Level FeignClientLoggerLevel() { 17 | return Logger.Level.FULL; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo-eureka-server/src/main/java/com/lynchj/demoeurekaserver/DemoEurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoeurekaserver; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:注册中心启动入口 10 | * @CreateDate:1:12 PM 2018/10/22 11 | */ 12 | @SpringBootApplication 13 | /** 开启 Eureka 注册中心服务 */ 14 | @EnableEurekaServer 15 | public class DemoEurekaServerApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(DemoEurekaServerApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/controller/LocalController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.controller; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:网关本地的 Controller 10 | * @CreateDate:1:33 PM 2018/10/30 11 | */ 12 | @RestController 13 | @RequestMapping( 14 | value = "/local", 15 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 16 | ) 17 | public class LocalController { 18 | 19 | @RequestMapping(value = "/testOne") 20 | public String testOne() { 21 | 22 | return "testOne"; 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/component/ServiceInfo.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.component; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.web.context.WebServerInitializedEvent; 5 | import org.springframework.context.ApplicationListener; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:当前服务的信息 11 | * @CreateDate:3:55 PM 2018/10/31 12 | */ 13 | @Data 14 | @Component 15 | public class ServiceInfo implements ApplicationListener { 16 | 17 | private Integer port; 18 | 19 | @Override 20 | public void onApplicationEvent(WebServerInitializedEvent event) { 21 | this.port = event.getWebServer().getPort(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/HystrixAndFeignFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign; 2 | 3 | import com.lynchj.demoorder.feign.hystrix.HystrixAndFeignHystrix; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:Hystrix 结合 Feign 案例 11 | * @CreateDate:10:23 AM 2018/10/29 12 | */ 13 | @FeignClient(name = "demo-goods", fallback = HystrixAndFeignHystrix.class) 14 | public interface HystrixAndFeignFeign { 15 | 16 | @RequestMapping(value = "/hystrixAndFeign/getUser") 17 | String getUser(@RequestParam(name = "username") String username); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/controller/HystrixAndFeignController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | * @Author:大漠知秋 8 | * @Description:Hystrix 结合 Feign 案例 9 | * @CreateDate:10:23 AM 2018/10/29 10 | */ 11 | @RestController 12 | @RequestMapping("/hystrixAndFeign") 13 | public class HystrixAndFeignController { 14 | 15 | @RequestMapping(value = "/getUser") 16 | public String getUser(String username) { 17 | 18 | if ("SpringCloud".equals(username)) { 19 | return "Hello " + username; 20 | } else { 21 | throw new RuntimeException(); 22 | } 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/FeignUploadFileSupportConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import feign.codec.Encoder; 4 | import feign.form.spring.SpringFormEncoder; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Primary; 8 | import org.springframework.context.annotation.Scope; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description:Feign Client 进行上传文件配置类 13 | * @CreateDate:3:48 PM 2018/10/25 14 | */ 15 | @Configuration 16 | public class FeignUploadFileSupportConfiguration { 17 | 18 | @Bean 19 | @Primary 20 | @Scope("prototype") 21 | public Encoder multipartFormEncoder() { 22 | return new SpringFormEncoder(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo-config-server/src/main/java/com/lynchj/democonfigserver/DemoConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.democonfigserver; 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.config.server.EnableConfigServer; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:Config Server 服务启动入口 11 | * @CreateDate:4:35 PM 2018/11/1 12 | */ 13 | @SpringBootApplication 14 | /** 开启配置中心服务 */ 15 | @EnableConfigServer 16 | /** 开启服务发现 */ 17 | @EnableDiscoveryClient 18 | public class DemoConfigServerApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(DemoConfigServerApplication.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo-admin-server/src/main/java/com/lynchj/demoadminserver/DemoAdminServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoadminserver; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:demo-admin-server 服务启动入口 11 | * @CreateDate:4:54 PM 2018/10/29 12 | */ 13 | @SpringBootApplication 14 | /** 开启服务发现 */ 15 | @EnableDiscoveryClient 16 | /** 开启监控平台 */ 17 | @EnableAdminServer 18 | public class DemoAdminServerApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(DemoAdminServerApplication.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/HystrixAndFeignController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.feign.HystrixAndFeignFeign; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import javax.annotation.Resource; 8 | 9 | /** 10 | * @Author:大漠知秋 11 | * @Description:Hystrix 结合 Feign 案例 12 | * @CreateDate:10:23 AM 2018/10/29 13 | */ 14 | @RestController 15 | @RequestMapping("/hystrixAndFeign") 16 | public class HystrixAndFeignController { 17 | 18 | @Resource 19 | private HystrixAndFeignFeign hystrixAndFeignFeign; 20 | 21 | @RequestMapping(value = "/getUser") 22 | public String getUser(String username) { 23 | 24 | return hystrixAndFeignFeign.getUser(username); 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/exception/GlobalExceptionHandle.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.exception; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:全局异常处理器 11 | * @CreateDate:3:28 PM 2018/10/30 12 | */ 13 | @ControllerAdvice 14 | @Slf4j 15 | public class GlobalExceptionHandle { 16 | 17 | @ExceptionHandler(value = Exception.class) 18 | @ResponseBody 19 | public String handle(Exception e) { 20 | if (e instanceof RuntimeException) { 21 | return "Zuul-全局捕获-自定义的错误信息"; 22 | } else { 23 | return "Zuul-全局捕获-系统繁忙,请稍后再试"; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-config-server/src/main/java/com/lynchj/democonfigserver/config/SpringSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.democonfigserver.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:Spring Security 配置 10 | * @CreateDate:2:54 PM 2018/10/23 11 | */ 12 | @Configuration 13 | public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter { 14 | 15 | @Override 16 | protected void configure(HttpSecurity http) throws Exception { 17 | super.configure(http); 18 | // 关闭 CSRF 19 | http.csrf().disable() 20 | .antMatcher("/health").anonymous(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /demo-eureka-server/src/main/java/com/lynchj/demoeurekaserver/config/SpringSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoeurekaserver.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:Spring Security 配置 10 | * @CreateDate:2:54 PM 2018/10/23 11 | */ 12 | @Configuration 13 | public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter { 14 | 15 | @Override 16 | protected void configure(HttpSecurity http) throws Exception { 17 | super.configure(http); 18 | // 关闭 CSRF 19 | http.csrf().disable() 20 | .antMatcher("/health").anonymous(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/exception/GlobalExceptionHandle.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.exception; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:全局异常处理器 11 | * @CreateDate:3:28 PM 2018/10/30 12 | */ 13 | @ControllerAdvice 14 | @Slf4j 15 | public class GlobalExceptionHandle { 16 | 17 | @ExceptionHandler(value = Exception.class) 18 | @ResponseBody 19 | public String handle(Exception e) { 20 | if (e instanceof RuntimeException) { 21 | return "demo-goods-全局捕获-自定义的错误信息"; 22 | } else { 23 | return "demo-goods-全局捕获-系统繁忙,请稍后再试"; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/exception/GlobalExceptionHandle.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.exception; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:全局异常处理器 11 | * @CreateDate:3:28 PM 2018/10/30 12 | */ 13 | @ControllerAdvice 14 | @Slf4j 15 | public class GlobalExceptionHandle { 16 | 17 | @ExceptionHandler(value = Exception.class) 18 | @ResponseBody 19 | public String handle(Exception e) { 20 | if (e instanceof RuntimeException) { 21 | return "demo-order-全局捕获-自定义的错误信息"; 22 | } else { 23 | return "demo-order-全局捕获-系统繁忙,请稍后再试"; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/DemoGoodsApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods; 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.hystrix.EnableHystrix; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | 9 | /** 10 | * @Author:大漠知秋 11 | * @Description:demo-goods 服务启动入口 12 | * @CreateDate:1:36 PM 2018/10/22 13 | */ 14 | @SpringBootApplication 15 | /** 开启服务发现 */ 16 | @EnableDiscoveryClient 17 | /** 开启 Feign 扫描支持 */ 18 | @EnableFeignClients 19 | /** 启动断路器功能 */ 20 | @EnableHystrix 21 | public class DemoGoodsApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(DemoGoodsApplication.class, args); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/DemoApiZuulApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul; 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.hystrix.EnableHystrix; 7 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 8 | 9 | /** 10 | * @Author:大漠知秋 11 | * @Description:demo-api-zuul 服务启动入口 12 | * @CreateDate:7:22 PM 2018/10/29 13 | */ 14 | @SpringBootApplication 15 | /** 开启服务发现 */ 16 | @EnableDiscoveryClient 17 | /** 开启网关代理 */ 18 | @EnableZuulProxy 19 | /** 启动断路器功能 */ 20 | @EnableHystrix 21 | public class DemoApiZuulApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(DemoApiZuulApplication.class, args); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/GitHubFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description:使用 Feign 访问 Github 查询 API 13 | * @CreateDate:2:36 PM 2018/10/24 14 | */ 15 | @FeignClient(name = "github-client", url = "https://api.github.com") 16 | public interface GitHubFeign { 17 | 18 | @RequestMapping( 19 | value = "/search/repositories", 20 | method = RequestMethod.GET, 21 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 22 | ) 23 | ResponseEntity searchRepo(@RequestParam("q") String q); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/feign/OrderFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.feign; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:访问 Order 服务的 Feign 11 | * @CreateDate:11:19 AM 2018/10/24 12 | */ 13 | @FeignClient(value = "demo-order") 14 | public interface OrderFeign { 15 | 16 | @RequestMapping( 17 | value = "/order/getPort", 18 | method = RequestMethod.GET, 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | String getPort(); 22 | 23 | @RequestMapping( 24 | value = "/order/getPort", 25 | method = RequestMethod.POST, 26 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 27 | ) 28 | String getPortByPost(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/GrayController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.component.ServiceInfo; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.annotation.Resource; 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | /** 12 | * @Author:大漠知秋 13 | * @Description:灰度发布测试 Controller 14 | * @CreateDate:3:05 PM 2018/10/31 15 | */ 16 | @RestController 17 | @RequestMapping( 18 | value = "/gray", 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | public class GrayController { 22 | 23 | @Resource 24 | private ServiceInfo serviceInfo; 25 | 26 | @RequestMapping(value = "/getPort") 27 | public String getPort(HttpServletRequest request) { 28 | return String.valueOf(serviceInfo.getPort()); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/GoodsFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | /** 9 | * @Author:大漠知秋 10 | * @Description:访问 Goods 服务的 Feign 11 | * @CreateDate:11:19 AM 2018/10/24 12 | */ 13 | @FeignClient(value = "demo-goods") 14 | public interface GoodsFeign { 15 | 16 | @RequestMapping( 17 | value = "/goods/getPort", 18 | method = RequestMethod.GET, 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | String getPort(); 22 | 23 | @RequestMapping( 24 | value = "/goods/getPort", 25 | method = RequestMethod.POST, 26 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 27 | ) 28 | String getPortByPost(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/main/java/com/lynchj/demohystrixdashboard/DemoHystrixDashboardApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demohystrixdashboard; 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.hystrix.dashboard.EnableHystrixDashboard; 7 | import org.springframework.cloud.netflix.turbine.EnableTurbine; 8 | 9 | /** 10 | * @Author:大漠知秋 11 | * @Description:Hystrix Dashboard 服务启动入口 12 | * @CreateDate:11:27 AM 2018/10/29 13 | */ 14 | @SpringBootApplication 15 | /** 开启服务发现 */ 16 | @EnableDiscoveryClient 17 | /** 开启 Hystrix Dashboard 监控功能 */ 18 | @EnableHystrixDashboard 19 | /** 开启 Hystrix 集群监控 */ 20 | @EnableTurbine 21 | public class DemoHystrixDashboardApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(DemoHystrixDashboardApplication.class, args); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/ConfigServerInfoController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.component.ConfigServerInfoProperties; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description:测试 Config Server Controller 13 | * @CreateDate:5:18 PM 2018/11/1 14 | */ 15 | @RestController 16 | @RequestMapping( 17 | value = "configServerInfo", 18 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 19 | ) 20 | public class ConfigServerInfoController { 21 | 22 | @Resource 23 | private ConfigServerInfoProperties configServerInfoProperties; 24 | 25 | @RequestMapping(value = "getAll") 26 | public String getAll() { 27 | 28 | return configServerInfoProperties.getOne() + " === " + configServerInfoProperties.getTwo(); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/controller/FeignUploadFileController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.controller; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import org.springframework.web.multipart.MultipartFile; 8 | 9 | /** 10 | * @Author:大漠知秋 11 | * @Description:Feign 上传文件 Controller 12 | * @CreateDate:3:27 PM 2018/10/25 13 | */ 14 | @RestController 15 | @RequestMapping("/upload") 16 | public class FeignUploadFileController { 17 | 18 | @RequestMapping( 19 | value = "/file", 20 | method = RequestMethod.POST, 21 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE, 22 | consumes = MediaType.MULTIPART_FORM_DATA_VALUE 23 | ) 24 | public String file(MultipartFile file) { 25 | System.err.println("原始文件名:" + file.getOriginalFilename()); 26 | System.out.println("文件大小:" + file.getSize()); 27 | return "上传成功"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/FeignGetInterceptorFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign; 2 | 3 | import com.lynchj.demoorder.model.User; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.http.MediaType; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | @FeignClient(name = "demo-goods") 12 | public interface FeignGetInterceptorFeign { 13 | 14 | @RequestMapping( 15 | value = "/feignGet/addUser", 16 | method = RequestMethod.GET, 17 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 18 | ) 19 | ResponseEntity addUser(User user); 20 | 21 | @RequestMapping( 22 | value = "/feignGet/updateUser", 23 | method = RequestMethod.POST, 24 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 25 | ) 26 | ResponseEntity updateUser(@RequestBody User user); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/RibbonRestTemplateController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @Author:大漠知秋 13 | * @Description:Ribbon 客户端负载均衡 请求 Controller 14 | * @CreateDate:6:02 PM 2018/10/25 15 | */ 16 | @RestController 17 | @RequestMapping( 18 | value = "/ribbon", 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | public class RibbonRestTemplateController { 22 | 23 | @Resource 24 | private RestTemplate restTemplate; 25 | 26 | @RequestMapping( 27 | value = "/getPort", 28 | method = RequestMethod.GET 29 | ) 30 | public String getPort() { 31 | return restTemplate.getForObject("http://demo-goods/goods/getPort", String.class); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/FeignUploadFileController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.feign.FeignUploadFileFeign; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.*; 7 | import org.springframework.web.multipart.MultipartFile; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @Author:大漠知秋 13 | * @Description:Feign 上传文件 Controller 14 | * @CreateDate:3:27 PM 2018/10/25 15 | */ 16 | @RestController 17 | @RequestMapping("/upload") 18 | public class FeignUploadFileController { 19 | 20 | @Resource 21 | private FeignUploadFileFeign feignUploadFileFeign; 22 | 23 | @RequestMapping( 24 | value = "/file", 25 | method = RequestMethod.POST, 26 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE, 27 | consumes = MediaType.MULTIPART_FORM_DATA_VALUE 28 | ) 29 | public ResponseEntity file(@RequestPart("file") MultipartFile file) { 30 | return feignUploadFileFeign.file(file); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/feign/FeignUploadFileFeign.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.feign; 2 | 3 | import com.lynchj.demoorder.config.FeignUploadFileSupportConfiguration; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.http.MediaType; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RequestPart; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | /** 13 | * @Author:大漠知秋 14 | * @Description:Feign 上传文件 15 | * @CreateDate:3:27 PM 2018/10/25 16 | */ 17 | @FeignClient(name = "demo-goods", configuration = FeignUploadFileSupportConfiguration.class) 18 | public interface FeignUploadFileFeign { 19 | 20 | @RequestMapping( 21 | value = "/upload/file", 22 | method = RequestMethod.POST, 23 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE, 24 | consumes = MediaType.MULTIPART_FORM_DATA_VALUE 25 | ) 26 | ResponseEntity file(@RequestPart("file") MultipartFile file); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/HystrixIntroductionController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @Author:大漠知秋 9 | * @Description:Hystrix 入门案例 10 | * @CreateDate:10:23 AM 2018/10/29 11 | */ 12 | @RestController 13 | @RequestMapping("/hystrixIntroduction") 14 | public class HystrixIntroductionController { 15 | 16 | @RequestMapping(value = "/getUser") 17 | @HystrixCommand(fallbackMethod = "fallbackGetUser") 18 | public String getUser(String username) { 19 | 20 | if ("SpringCloud".equals(username)) { 21 | return "Hello " + username; 22 | } else { 23 | throw new RuntimeException("哈哈哈,出错了"); 24 | // throw new HystrixBadRequestException("Test"); 25 | } 26 | 27 | } 28 | 29 | public String fallbackGetUser(String username, Throwable throwable) { 30 | System.err.println(throwable.fillInStackTrace()); 31 | return "No Hello " + username; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/GitHubController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.feign.GitHubFeign; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import javax.annotation.Resource; 12 | 13 | /** 14 | * @Author:大漠知秋 15 | * @Description:使用 Feign 访问 Github 查询 API 16 | * @CreateDate:2:42 PM 2018/10/24 17 | */ 18 | @RestController 19 | @RequestMapping( 20 | value = "/github", 21 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 22 | ) 23 | public class GitHubController { 24 | 25 | @Resource 26 | private GitHubFeign gitHubFeign; 27 | 28 | @RequestMapping( 29 | value = "/search/repositories", 30 | method = RequestMethod.GET 31 | ) 32 | ResponseEntity searchRepo(@RequestParam("q") String q) { 33 | return gitHubFeign.searchRepo(q); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description Order 服务的 Controller 13 | * @CreateDate:11:18 AM 2018/10/24 14 | */ 15 | @RestController 16 | @RequestMapping( 17 | value = "/order", 18 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 19 | ) 20 | public class OrderController { 21 | 22 | @RequestMapping( 23 | value = "/getPort", 24 | method = RequestMethod.GET 25 | ) 26 | public String getPort(HttpServletRequest request) { 27 | 28 | return String.valueOf(request.getServerPort()); 29 | 30 | } 31 | 32 | @RequestMapping( 33 | value = "/getPort", 34 | method = RequestMethod.POST 35 | ) 36 | public String getPortByPost(HttpServletRequest request) { 37 | 38 | return String.valueOf(request.getServerPort()); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.controller; 2 | 3 | import com.lynchj.demogoods.feign.OrderFeign; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @Author:大漠知秋 13 | * @Description:访问 Order 服务的 Controller 14 | * @CreateDate:11:18 AM 2018/10/24 15 | */ 16 | @RestController 17 | @RequestMapping( 18 | value = "/order", 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | public class OrderController { 22 | 23 | @Resource 24 | private OrderFeign orderFeign; 25 | 26 | @RequestMapping( 27 | value = "/getPort", 28 | method = RequestMethod.GET 29 | ) 30 | public String getPort() { 31 | 32 | return orderFeign.getPort(); 33 | 34 | } 35 | 36 | @RequestMapping( 37 | value = "/getPort", 38 | method = RequestMethod.POST 39 | ) 40 | public String getPortByPost() { 41 | 42 | return orderFeign.getPortByPost(); 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/DemoOrderApplication.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder; 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.cloud.netflix.hystrix.EnableHystrix; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.web.client.RestTemplate; 11 | 12 | /** 13 | * @Author:大漠知秋 14 | * @Description:demo-order 服务启动入口 15 | * @CreateDate:1:36 PM 2018/10/22 16 | */ 17 | @SpringBootApplication 18 | /** 开启服务发现 */ 19 | @EnableDiscoveryClient 20 | /** 开启 Feign 扫描支持 */ 21 | @EnableFeignClients 22 | /** 启动断路器功能 */ 23 | @EnableHystrix 24 | public class DemoOrderApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(DemoOrderApplication.class, args); 28 | } 29 | 30 | /** 31 | * Ribbon Http 请求 客户端负载均衡器 32 | */ 33 | @Bean 34 | @LoadBalanced 35 | public RestTemplate restTemplate() { 36 | return new RestTemplate(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/controller/GoodsController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.controller; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description Goods 服务的 Controller 13 | * @CreateDate:11:18 AM 2018/10/24 14 | */ 15 | @RestController 16 | @RequestMapping( 17 | value = "/goods", 18 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 19 | ) 20 | public class GoodsController { 21 | 22 | @RequestMapping( 23 | value = "/getPort", 24 | method = RequestMethod.GET 25 | ) 26 | public String getPort(HttpServletRequest request) { 27 | 28 | // throw new RuntimeException(); 29 | return String.valueOf(request.getServerPort()); 30 | 31 | } 32 | 33 | @RequestMapping( 34 | value = "/getPort", 35 | method = RequestMethod.POST 36 | ) 37 | public String getPortByPost(HttpServletRequest request) { 38 | 39 | return String.valueOf(request.getServerPort()); 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/GoodsController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.feign.GoodsFeign; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @Author:大漠知秋 13 | * @Description:访问 Goods 服务的 Controller 14 | * @CreateDate:11:18 AM 2018/10/24 15 | */ 16 | @RestController 17 | @RequestMapping( 18 | value = "/goods", 19 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 20 | ) 21 | public class GoodsController { 22 | 23 | @Resource 24 | private GoodsFeign goodsFeign; 25 | 26 | @RequestMapping( 27 | value = "/getPort", 28 | method = RequestMethod.GET 29 | ) 30 | public String getPort() { 31 | 32 | // throw new IllegalStateException(); 33 | return goodsFeign.getPort(); 34 | 35 | } 36 | 37 | @RequestMapping( 38 | value = "/getPort", 39 | method = RequestMethod.POST 40 | ) 41 | public String getPortByPost() { 42 | 43 | return goodsFeign.getPortByPost(); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/FeignClientOkHttpConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import feign.Feign; 4 | import okhttp3.ConnectionPool; 5 | import okhttp3.OkHttpClient; 6 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 8 | import org.springframework.cloud.openfeign.FeignAutoConfiguration; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * @Author:大漠知秋 16 | * @Description:Feign 底层使用 OKHttp 访问配置 17 | * @CreateDate:1:59 PM 2018/10/25 18 | */ 19 | @Configuration 20 | @ConditionalOnClass(Feign.class) 21 | @AutoConfigureBefore(FeignAutoConfiguration.class) 22 | public class FeignClientOkHttpConfiguration { 23 | 24 | @Bean 25 | public OkHttpClient okHttpClient() { 26 | return new OkHttpClient.Builder() 27 | // 连接超时 28 | .connectTimeout(20, TimeUnit.SECONDS) 29 | // 响应超时 30 | .readTimeout(20, TimeUnit.SECONDS) 31 | // 写超时 32 | .writeTimeout(20, TimeUnit.SECONDS) 33 | // 是否自动重连 34 | .retryOnConnectionFailure(true) 35 | // 连接池 36 | .connectionPool(new ConnectionPool()) 37 | .build(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/controller/FeignGetInterceptorController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.controller; 2 | 3 | import com.lynchj.demogoods.model.User; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.Date; 11 | 12 | /** 13 | * @Author:大漠知秋 14 | * @Description:测试 FeignGetInterceptor 的 Controller 15 | * @CreateDate:2:38 PM 2018/10/25 16 | */ 17 | @RestController 18 | @RequestMapping("/feignGet") 19 | public class FeignGetInterceptorController { 20 | 21 | @RequestMapping( 22 | value = "/addUser", 23 | method = RequestMethod.GET, 24 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 25 | ) 26 | User addUser(User user) { 27 | user.setAge(user.getAge() + 1); 28 | user.setUsername(user.getUsername() + "1"); 29 | user.setBirthday(new Date()); 30 | return user; 31 | } 32 | 33 | @RequestMapping( 34 | value = "/updateUser", 35 | method = RequestMethod.POST, 36 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 37 | ) 38 | User updateUser(@RequestBody User user) { 39 | user.setAge(user.getAge() + 1); 40 | user.setUsername(user.getUsername() + "1"); 41 | user.setBirthday(new Date()); 42 | return user; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /demo-admin-server/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 17000 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-admin-server 24 | 25 | ### 日志配置 26 | logback: 27 | spring: 28 | level: INFO 29 | project: 30 | level: INFO 31 | 32 | ### 注册中心配置 33 | eureka: 34 | instance: 35 | # 主机名 36 | hostname: localhost 37 | # 使用 ip 注册到注册中心实例化 38 | prefer-ip-address: true 39 | client: 40 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 41 | secure-port-enabled: false 42 | ssl: 43 | # 开启 Https 注册到注册中心使用的证书 44 | key-store: EurekaClient.p12 45 | # 开启 Https 注册到注册中心使用的证书密码 46 | key-store-password: 123456 47 | security: 48 | user: 49 | name: eureka-server 50 | password: 8e9lx7LuP3436gfsg 51 | # Spring Cloud Eureka 注册中心地址 52 | service-url: 53 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 54 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 55 | registry-fetch-interval-seconds: 30 -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/controller/FeignGetInterceptorController.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.controller; 2 | 3 | import com.lynchj.demoorder.feign.FeignGetInterceptorFeign; 4 | import com.lynchj.demoorder.model.User; 5 | import org.springframework.http.MediaType; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import javax.annotation.Resource; 13 | 14 | /** 15 | * @Author:大漠知秋 16 | * @Description:测试 FeignGetInterceptor 的 Controller 17 | * @CreateDate:2:38 PM 2018/10/25 18 | */ 19 | @RestController 20 | @RequestMapping("/feignGet") 21 | public class FeignGetInterceptorController { 22 | 23 | @Resource 24 | private FeignGetInterceptorFeign feignGetInterceptorFeign; 25 | 26 | @RequestMapping( 27 | value = "/addUser", 28 | method = RequestMethod.GET, 29 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 30 | ) 31 | ResponseEntity addUser(User user) { 32 | return feignGetInterceptorFeign.addUser(user); 33 | } 34 | 35 | @RequestMapping( 36 | value = "/updateUser", 37 | method = RequestMethod.POST, 38 | produces = MediaType.APPLICATION_JSON_UTF8_VALUE 39 | ) 40 | ResponseEntity updateUser(@RequestBody User user) { 41 | return feignGetInterceptorFeign.updateUser(user); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 9090 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-hystrix-dashboard 24 | 25 | ### 日志配置 26 | logback: 27 | spring: 28 | level: INFO 29 | project: 30 | level: INFO 31 | 32 | ### 注册中心配置 33 | eureka: 34 | instance: 35 | # 主机名 36 | hostname: localhost 37 | # 使用 ip 注册到注册中心实例化 38 | prefer-ip-address: true 39 | client: 40 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 41 | secure-port-enabled: false 42 | ssl: 43 | # 开启 Https 注册到注册中心使用的证书 44 | key-store: EurekaClient.p12 45 | # 开启 Https 注册到注册中心使用的证书密码 46 | key-store-password: 123456 47 | security: 48 | user: 49 | name: eureka-server 50 | password: 8e9lx7LuP3436gfsg 51 | # Spring Cloud Eureka 注册中心地址 52 | service-url: 53 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 54 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 55 | registry-fetch-interval-seconds: 30 56 | 57 | ### Hystrix Turbin 配置 58 | turbine: 59 | app-config: demo-goods,demo-order,demo-api-zuul 60 | cluster-name-expression: "'default'" -------------------------------------------------------------------------------- /demo-admin-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-admin-server 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-admin-server 12 | 演示样例 Admin 服务 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | de.codecentric 31 | spring-boot-admin-starter-server 32 | ${spring-boot-admin-starter-server.version} 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.apache.httpcomponents 40 | httpclient 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /demo-eureka-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-eureka-server 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-eureka-server 12 | 演示样例 Eureka Server 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-server 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-security 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.apache.httpcomponents 42 | httpclient 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/filters/PostFirstFilter.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import com.netflix.zuul.exception.ZuulException; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.stereotype.Component; 11 | 12 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; 13 | 14 | /** 15 | * @Author:大漠知秋 16 | * @Description:测试使用第一个 post Filter 17 | * @CreateDate:4:34 PM 2018/10/30 18 | */ 19 | @Component 20 | @Slf4j 21 | public class PostFirstFilter extends ZuulFilter { 22 | 23 | @Override 24 | public String filterType() { 25 | return POST_TYPE; 26 | } 27 | 28 | @Override 29 | public int filterOrder() { 30 | return 0; 31 | } 32 | 33 | @Override 34 | public boolean shouldFilter() { 35 | return true; 36 | } 37 | 38 | @Override 39 | public Object run() throws ZuulException { 40 | 41 | log.info("经过第一个 post 过滤器"); 42 | 43 | RequestContext ctx = RequestContext.getCurrentContext(); 44 | String responseBody = ctx.getResponseBody(); 45 | if (StringUtils.isNotBlank(responseBody)) { 46 | // 说明逻辑没有通过 47 | // 设置编码 48 | ctx.getResponse().setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); 49 | ctx.getResponse().setCharacterEncoding("UTF-8"); 50 | // 更改响应状态 51 | ctx.setResponseStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); 52 | // 替换掉响应报文 53 | ctx.setResponseBody(responseBody); 54 | } 55 | 56 | return null; 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/filters/GrayFilter.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import com.netflix.zuul.exception.ZuulException; 6 | import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; 14 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 15 | 16 | /** 17 | * @Author:大漠知秋 18 | * @Description:灰度发布 Filter 19 | * @CreateDate:2:38 PM 2018/10/31 20 | */ 21 | @Component 22 | @Slf4j 23 | public class GrayFilter extends ZuulFilter { 24 | 25 | @Override 26 | public String filterType() { 27 | return PRE_TYPE; 28 | } 29 | 30 | @Override 31 | public int filterOrder() { 32 | return PRE_DECORATION_FILTER_ORDER - 1; 33 | } 34 | 35 | @Override 36 | public boolean shouldFilter() { 37 | return true; 38 | } 39 | 40 | /** 启用 灰度发布 标识 */ 41 | private static final String GRAY_MARK = "enable"; 42 | 43 | @Override 44 | public Object run() throws ZuulException { 45 | HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); 46 | String mark = request.getHeader("gray_mark"); 47 | if (StringUtils.isNotBlank(mark) && GRAY_MARK.equals(mark)) { 48 | RibbonFilterContextHolder.getCurrentContext() 49 | .add("host-mark", "gray-host"); 50 | } else { 51 | RibbonFilterContextHolder.getCurrentContext() 52 | .add("host-mark", "running-host"); 53 | } 54 | return null; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/filters/PreFirstFilter.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.filters; 2 | 3 | import com.lynchj.demoapizuul.constants.SessionContants; 4 | import com.netflix.zuul.ZuulFilter; 5 | import com.netflix.zuul.context.RequestContext; 6 | import com.netflix.zuul.exception.ZuulException; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 14 | 15 | /** 16 | * @Author:大漠知秋 17 | * @Description:测试使用第一个 pre Filter 18 | * @CreateDate:4:34 PM 2018/10/30 19 | */ 20 | @Component 21 | @Slf4j 22 | public class PreFirstFilter extends ZuulFilter { 23 | 24 | @Override 25 | public String filterType() { 26 | return PRE_TYPE; 27 | } 28 | 29 | @Override 30 | public int filterOrder() { 31 | return 0; 32 | } 33 | 34 | @Override 35 | public boolean shouldFilter() { 36 | return false; 37 | } 38 | 39 | @Override 40 | public Object run() throws ZuulException { 41 | 42 | log.info("经过第一个 pre 过滤器"); 43 | 44 | RequestContext ctx = RequestContext.getCurrentContext(); 45 | HttpServletRequest request = ctx.getRequest(); 46 | if (StringUtils.isBlank(request.getHeader("a"))) { 47 | // 未经过逻辑 48 | // 用来给后面的 Filter 标识,是否继续执行 49 | ctx.set(SessionContants.LOGIC_IS_SUCCESS, false); 50 | // 返回信息 51 | ctx.setResponseBody(String.format(SessionContants.ERROR_RESPONSE_BODY, "a Header头不足")); 52 | // 对该请求禁止路由,禁止访问下游服务 53 | ctx.setSendZuulResponse(false); 54 | return null; 55 | } 56 | 57 | // 用来给后面的 Filter 标识,是否继续执行 58 | ctx.set(SessionContants.LOGIC_IS_SUCCESS, true); 59 | return null; 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /demo-config-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-config-server 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-config-server 12 | 演示样例 Config Server 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-config-server 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-bus-amqp 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-security 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.httpcomponents 52 | httpclient 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-hystrix-dashboard 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-hystrix-dashboard 12 | 演示样例 Hystrix Dashboard 服务 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-netflix-hystrix-dashboard 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-netflix-turbine 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.apache.httpcomponents 44 | httpclient 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/filters/PreSecondFilter.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.filters; 2 | 3 | import com.lynchj.demoapizuul.constants.SessionContants; 4 | import com.netflix.zuul.ZuulFilter; 5 | import com.netflix.zuul.context.RequestContext; 6 | import com.netflix.zuul.exception.ZuulException; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 14 | 15 | /** 16 | * @Author:大漠知秋 17 | * @Description:测试使用第二个 pre Filter 18 | * @CreateDate:4:34 PM 2018/10/30 19 | */ 20 | @Component 21 | @Slf4j 22 | public class PreSecondFilter extends ZuulFilter { 23 | 24 | @Override 25 | public String filterType() { 26 | return PRE_TYPE; 27 | } 28 | 29 | @Override 30 | public int filterOrder() { 31 | return 2; 32 | } 33 | 34 | @Override 35 | public boolean shouldFilter() { 36 | RequestContext ctx = RequestContext.getCurrentContext(); 37 | Object logicIsSuccess = ctx.get(SessionContants.LOGIC_IS_SUCCESS); 38 | return logicIsSuccess == null ? false : (boolean) logicIsSuccess; 39 | } 40 | 41 | @Override 42 | public Object run() throws ZuulException { 43 | 44 | log.info("经过第二个 pre 过滤器"); 45 | 46 | RequestContext ctx = RequestContext.getCurrentContext(); 47 | HttpServletRequest request = ctx.getRequest(); 48 | if (StringUtils.isBlank(request.getParameter("b"))) { 49 | // 未经过逻辑 50 | // 用来给后面的 Filter 标识,是否继续执行 51 | ctx.set(SessionContants.LOGIC_IS_SUCCESS, false); 52 | // 返回信息 53 | ctx.setResponseBody(String.format(SessionContants.ERROR_RESPONSE_BODY, "b 参数头不足")); 54 | // 对该请求禁止路由,禁止访问下游服务 55 | ctx.setSendZuulResponse(false); 56 | return null; 57 | } 58 | 59 | // 用来给后面的 Filter 标识,是否继续执行 60 | ctx.set(SessionContants.LOGIC_IS_SUCCESS, true); 61 | return null; 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/fallback/ZuulFallback.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.fallback; 2 | 3 | import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; 4 | import org.springframework.http.HttpHeaders; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.http.client.ClientHttpResponse; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.io.ByteArrayInputStream; 11 | import java.io.InputStream; 12 | 13 | /** 14 | * @Author:大漠知秋 15 | * @Description:Zuul Fallback 机制 16 | * @CreateDate:5:15 PM 2018/9/27 17 | */ 18 | @Component 19 | public class ZuulFallback implements FallbackProvider { 20 | 21 | /** 22 | * 可以配置指定的路由,值为 serviceId,如:demo-order 23 | */ 24 | @Override 25 | public String getRoute() { 26 | return "*"; 27 | } 28 | 29 | @Override 30 | public ClientHttpResponse fallbackResponse(String route, Throwable cause) { 31 | return new ClientHttpResponse() { 32 | @Override 33 | public HttpStatus getStatusCode() { 34 | // 返回状态吗 35 | return HttpStatus.INTERNAL_SERVER_ERROR; 36 | } 37 | 38 | @Override 39 | public String getStatusText() { 40 | // 错误原因 41 | return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(); 42 | } 43 | 44 | @Override 45 | public void close() { 46 | } 47 | 48 | @Override 49 | public InputStream getBody() { 50 | // 定义自己的错误信息 51 | return new ByteArrayInputStream(("microservice error").getBytes()); 52 | } 53 | 54 | @Override 55 | public HttpHeaders getHeaders() { 56 | HttpHeaders headers = new HttpHeaders(); 57 | headers.setContentType(MediaType.APPLICATION_JSON); 58 | return headers; 59 | } 60 | 61 | @Override 62 | public int getRawStatusCode() { 63 | // TODO Auto-generated method stub 64 | return HttpStatus.INTERNAL_SERVER_ERROR.value(); 65 | } 66 | }; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /demo-goods/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-order/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-admin-server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-config-server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-eureka-server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | /log/server/demo-basic-finchley/${spring.application.name}.log 19 | 20 | /log/server/demo-basic-finchley/zip/demo-basic-finchley_log.${spring.application.name}.%i.zip 21 | 22 | 1 23 | 20 24 | 25 | 26 | 200MB 27 | 28 | 29 | [%d{yyyy-MM-dd HH:mm:ss.SSS} %thread] %-5level ${spring.application.name}-%logger{36} - %msg%n 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo-goods/src/main/java/com/lynchj/demogoods/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demogoods.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-admin-server/src/main/java/com/lynchj/demoadminserver/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoadminserver.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-config-server/src/main/java/com/lynchj/democonfigserver/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.democonfigserver.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-eureka-server/src/main/java/com/lynchj/demoeurekaserver/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoeurekaserver.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-hystrix-dashboard/src/main/java/com/lynchj/demohystrixdashboard/config/EurekaHttpsClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demohystrixdashboard.config; 2 | 3 | import com.netflix.discovery.DiscoveryClient; 4 | import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl; 5 | import lombok.Data; 6 | import org.apache.http.ssl.SSLContextBuilder; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import java.io.IOException; 14 | import java.security.KeyManagementException; 15 | import java.security.KeyStoreException; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.cert.CertificateException; 18 | 19 | /** 20 | * @Author:大漠知秋 21 | * @Description:Eureka Client 针对 Eureka Server 的 HTTPS 请求配置 22 | * @CreateDate:4:13 PM 2018/10/23 23 | */ 24 | @Data 25 | @Configuration 26 | @ConfigurationProperties(prefix = "eureka.client.ssl") 27 | public class EurekaHttpsClientConfiguration { 28 | 29 | private String keyStore; 30 | 31 | private String keyStorePassword; 32 | 33 | @Bean 34 | @ConditionalOnProperty( 35 | value = "eureka.client.secure-port-enabled", 36 | havingValue = "true" 37 | ) 38 | public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { 39 | EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder(); 40 | builder.withClientName("eureka-https-client"); 41 | SSLContext sslContext = new SSLContextBuilder() 42 | .loadTrustMaterial( 43 | this.getClass().getClassLoader().getResource(this.keyStore), this.keyStorePassword.toCharArray() 44 | ) 45 | .build(); 46 | builder.withCustomSSL(sslContext); 47 | 48 | builder.withMaxTotalConnections(10); 49 | builder.withMaxConnectionsPerHost(10); 50 | 51 | DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs(); 52 | args.setEurekaJerseyClient(builder.build()); 53 | return args; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/StaticBackupRegistryListConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import com.netflix.appinfo.DataCenterInfo; 4 | import com.netflix.appinfo.InstanceInfo; 5 | import com.netflix.appinfo.MyDataCenterInfo; 6 | import com.netflix.discovery.BackupRegistry; 7 | import com.netflix.discovery.shared.Application; 8 | import com.netflix.discovery.shared.Applications; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description:此类主要针对在项目启动之前,所有的 Eureka Server 都挂掉了, 13 | * 此时连接不到注册中心,获取不到 Service Registry 14 | * 当读取此配置作为 备份使用 Service Registry 15 | * 当然,这种情况就比较适用于服务端提供负载均衡或者服务 ip 地址相对固定的场景 16 | * @CreateDate:10:35 AM 2018/10/24 17 | */ 18 | public class StaticBackupRegistryListConfiguration implements BackupRegistry { 19 | 20 | private Applications localRegionApps = new Applications(); 21 | 22 | public StaticBackupRegistryListConfiguration() { 23 | Application orgApplication = new Application("org"); 24 | InstanceInfo orgInstancel1 = InstanceInfo.Builder.newBuilder() 25 | .setAppName("demo-goods") 26 | .setVIPAddress ("demo-goods") 27 | .setSecureVIPAddress ("demo-goods") 28 | .setInstanceId("demo-instance-1") 29 | .setHostName("127.0.0.1") 30 | .setIPAddr("127.0.0.1") 31 | .setPort(11200) 32 | .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn)) 33 | .setStatus(InstanceInfo.InstanceStatus.UP) 34 | .build(); 35 | InstanceInfo orgInstancel2 = InstanceInfo.Builder.newBuilder() 36 | .setAppName("demo-goods") 37 | .setVIPAddress ("demo-goods") 38 | .setSecureVIPAddress ("demo-goods") 39 | .setInstanceId("demo-instance-2") 40 | .setHostName("127.0.0.1") 41 | .setIPAddr("127.0.0.1") 42 | .setPort(11201) 43 | .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn)) 44 | .setStatus(InstanceInfo.InstanceStatus.UP) 45 | .build(); 46 | orgApplication.addInstance(orgInstancel1); 47 | orgApplication.addInstance(orgInstancel2); 48 | localRegionApps.addApplication(orgApplication); 49 | } 50 | 51 | @Override 52 | public Applications fetchRegistry() { 53 | return localRegionApps; 54 | } 55 | 56 | @Override 57 | public Applications fetchRegistry(String[] includeRemoteRegions) { 58 | return localRegionApps; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/config/StaticBackupRegistryListConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.config; 2 | 3 | import com.netflix.appinfo.DataCenterInfo; 4 | import com.netflix.appinfo.InstanceInfo; 5 | import com.netflix.appinfo.MyDataCenterInfo; 6 | import com.netflix.discovery.BackupRegistry; 7 | import com.netflix.discovery.shared.Application; 8 | import com.netflix.discovery.shared.Applications; 9 | 10 | /** 11 | * @Author:大漠知秋 12 | * @Description:此类主要针对在项目启动之前,所有的 Eureka Server 都挂掉了, 13 | * 此时连接不到注册中心,获取不到 Service Registry 14 | * 当读取此配置作为 备份使用 Service Registry 15 | * 当然,这种情况就比较适用于服务端提供负载均衡或者服务 ip 地址相对固定的场景 16 | * @CreateDate:10:35 AM 2018/10/24 17 | */ 18 | public class StaticBackupRegistryListConfiguration implements BackupRegistry { 19 | 20 | private Applications localRegionApps = new Applications(); 21 | 22 | public StaticBackupRegistryListConfiguration() { 23 | Application orgApplication = new Application("org"); 24 | InstanceInfo orgInstancel1 = InstanceInfo.Builder.newBuilder() 25 | .setAppName("demo-goods") 26 | .setVIPAddress ("demo-goods") 27 | .setSecureVIPAddress ("demo-goods") 28 | .setInstanceId("demo-instance-1") 29 | .setHostName("127.0.0.1") 30 | .setIPAddr("127.0.0.1") 31 | .setPort(11200) 32 | .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn)) 33 | .setStatus(InstanceInfo.InstanceStatus.UP) 34 | .build(); 35 | InstanceInfo orgInstancel2 = InstanceInfo.Builder.newBuilder() 36 | .setAppName("demo-goods") 37 | .setVIPAddress ("demo-goods") 38 | .setSecureVIPAddress ("demo-goods") 39 | .setInstanceId("demo-instance-2") 40 | .setHostName("127.0.0.1") 41 | .setIPAddr("127.0.0.1") 42 | .setPort(11201) 43 | .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn)) 44 | .setStatus(InstanceInfo.InstanceStatus.UP) 45 | .build(); 46 | orgApplication.addInstance(orgInstancel1); 47 | orgApplication.addInstance(orgInstancel2); 48 | localRegionApps.addApplication(orgApplication); 49 | } 50 | 51 | @Override 52 | public Applications fetchRegistry() { 53 | return localRegionApps; 54 | } 55 | 56 | @Override 57 | public Applications fetchRegistry(String[] includeRemoteRegions) { 58 | return localRegionApps; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /demo-config-server/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 8887 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-config-server 24 | # 开启安全控制 25 | security: 26 | user: 27 | # 用户名 28 | name: config-server 29 | # 密码 30 | password: 8e9lx7LuP3436gfsg 31 | boot: 32 | admin: 33 | client: 34 | # 基于 Spring Boot 项目的监控地址 35 | url: 'http://localhost:1700' 36 | instance: 37 | service-base-url: 'http://localhost:1700' 38 | cloud: 39 | config: 40 | server: 41 | git: 42 | # 地址 43 | uri: https://github.com/SlowSlicing/demo-spring-cloud-finchley.git 44 | # 用户名,如果需要的话 45 | # username: 46 | # 密码,如果需要的话 47 | # password: 48 | # 搜索目录,默认:/ 49 | # 可以根据需求添加多个目录,使用","分隔开 50 | search-paths: demo-config-info 51 | # 分支,默认:master 52 | default-label: master 53 | # RabbitMQ 配置 54 | rabbitmq: 55 | # 地址 56 | host: localhost 57 | # 端口 58 | port: 5672 59 | # 用户名 60 | username: admin 61 | # 密码 62 | password: nS8KiyIu0Y7LGbvE 63 | 64 | ### 日志配置 65 | logback: 66 | spring: 67 | level: INFO 68 | project: 69 | level: INFO 70 | 71 | ### 端点控制 72 | management: 73 | endpoints: 74 | web: 75 | exposure: 76 | # 开启指定端点、所有端点 77 | include: 'health' 78 | endpoint: 79 | health: 80 | # 总是表示详细信息的显示 81 | show-details: always 82 | 83 | ### 注册中心配置 84 | eureka: 85 | instance: 86 | # 主机名 87 | hostname: localhost 88 | # 使用 ip 注册到注册中心实例化 89 | prefer-ip-address: true 90 | client: 91 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 92 | secure-port-enabled: false 93 | ssl: 94 | # 开启 Https 注册到注册中心使用的证书 95 | key-store: EurekaClient.p12 96 | # 开启 Https 注册到注册中心使用的证书密码 97 | key-store-password: 123456 98 | security: 99 | user: 100 | name: eureka-server 101 | password: 8e9lx7LuP3436gfsg 102 | # Spring Cloud Eureka 注册中心地址 103 | service-url: 104 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 105 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 106 | registry-fetch-interval-seconds: 30 -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/config/AutoRefreshConfigServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; 10 | import org.springframework.cloud.endpoint.RefreshEndpoint; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.scheduling.annotation.EnableScheduling; 13 | import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; 14 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 15 | import org.springframework.scheduling.config.IntervalTask; 16 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 17 | 18 | import javax.annotation.Resource; 19 | 20 | /** 21 | * @Author:大漠知秋 22 | * @Description:自动去刷新配置中心的配置 23 | * @CreateDate:10:31 AM 2018/11/2 24 | */ 25 | @Slf4j 26 | @ConditionalOnClass(RefreshEndpoint.class) 27 | @ConditionalOnProperty( 28 | value = "spring.cloud.config.auto-refresh-config.enabled", 29 | havingValue = "true" 30 | ) 31 | @AutoConfigureAfter(RefreshAutoConfiguration.class) 32 | @ConfigurationProperties(prefix = "spring.cloud.config.auto-refresh-config") 33 | @Configuration 34 | public class AutoRefreshConfigServerConfiguration implements SchedulingConfigurer { 35 | 36 | /** 间隔刷新时间 */ 37 | private long refreshInterval; 38 | 39 | public long getRefreshInterval() { 40 | return refreshInterval; 41 | } 42 | 43 | public void setRefreshInterval(long refreshInterval) { 44 | this.refreshInterval = refreshInterval; 45 | } 46 | 47 | /** 刷新的端点 */ 48 | @Resource 49 | private RefreshEndpoint refreshEndpoint; 50 | 51 | @Override 52 | public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 53 | final long interval = getRefreshIntervalInMilliseconds(); 54 | 55 | log.info(String.format("Scheduling config refresh task with %s second delay", refreshInterval)); 56 | scheduledTaskRegistrar.addFixedDelayTask(new IntervalTask( 57 | () -> { 58 | refreshEndpoint.refresh(); 59 | }, interval, interval 60 | )); 61 | } 62 | 63 | /** 以毫秒为单位返回刷新间隔。 */ 64 | private long getRefreshIntervalInMilliseconds() { 65 | return refreshInterval; 66 | } 67 | 68 | /** 如果没有在上下文中注册,则启用调度程序。 */ 69 | @ConditionalOnMissingBean(ScheduledAnnotationBeanPostProcessor.class) 70 | @EnableScheduling 71 | @Configuration 72 | protected static class EnableSchedulingConfigProperties { 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /demo-order/src/main/java/com/lynchj/demoorder/interceptor/FeignRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoorder.interceptor; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import feign.RequestInterceptor; 6 | import feign.RequestTemplate; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.exception.ExceptionUtils; 9 | import org.springframework.http.HttpMethod; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.util.StringUtils; 12 | 13 | import javax.annotation.Resource; 14 | import java.io.IOException; 15 | import java.util.*; 16 | 17 | /** 18 | * @Author:大漠知秋 19 | * @Description:拦截使用 Get 请求,并且使用的时 POJO 请求方式的 Feign 请求 20 | * @CreateDate:2:24 PM 2018/10/25 21 | */ 22 | @Component 23 | @Slf4j 24 | public class FeignRequestInterceptor implements RequestInterceptor { 25 | 26 | @Resource 27 | private ObjectMapper objectMapper; 28 | 29 | @Override 30 | public void apply(RequestTemplate template) { 31 | if (HttpMethod.GET.name().equals(template.method()) 32 | && null != template.body()) { 33 | try { 34 | JsonNode jsonNode = objectMapper.readTree(template.body()); 35 | template.body(null); 36 | 37 | Map> queries = new HashMap<>(); 38 | buildQuery(jsonNode, "", queries); 39 | template.queries(queries); 40 | } catch (IOException e) { 41 | log.error("【拦截GET请求POJO方式】-出错了:{}", ExceptionUtils.getStackFrames(e)); 42 | throw new RuntimeException(); 43 | } 44 | } 45 | } 46 | 47 | private void buildQuery(JsonNode jsonNode, String path, Map> queries) { 48 | // 叶子节点 49 | if (!jsonNode.isContainerNode()) { 50 | if (jsonNode.isNull()) { 51 | return; 52 | } 53 | Collection values = queries.get(path); 54 | if (null == values) { 55 | values = new ArrayList<>(); 56 | queries.put(path, values); 57 | } 58 | values.add(jsonNode.asText()); 59 | return; 60 | } 61 | // 数组节点 62 | if (jsonNode.isArray()) { 63 | Iterator it = jsonNode.elements(); 64 | while (it.hasNext()) { 65 | buildQuery(it.next(), path, queries); 66 | } 67 | } else { 68 | Iterator> it = jsonNode.fields(); 69 | while (it.hasNext()) { 70 | Map.Entry entry = it.next(); 71 | if (StringUtils.hasText(path)) { 72 | buildQuery(entry.getValue(), path + "." + entry.getKey(), queries); 73 | } else { // 根节点 74 | buildQuery(entry.getValue(), entry.getKey(), queries); 75 | } 76 | } 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /demo-api-zuul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-api-zuul 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-api-zuul 12 | 演示样例 Order 服务 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-netflix-zuul 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-config-client 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-bus-amqp 42 | 43 | 44 | 45 | 46 | 47 | 48 | de.codecentric 49 | spring-boot-admin-starter-client 50 | ${spring-boot-admin-starter-client.version} 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.retry 58 | spring-retry 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.httpcomponents 66 | httpclient 67 | 68 | 69 | 70 | io.jmnarloch 71 | ribbon-discovery-filter-spring-cloud-starter 72 | ${ribbon-discovery-filter-spring-cloud-starter.version} 73 | 74 | 75 | 76 | com.squareup.okhttp3 77 | okhttp 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /demo-goods/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-goods 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-goods 12 | 演示样例 Goods 服务 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-openfeign 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-netflix-ribbon 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-netflix-hystrix 42 | 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-config-client 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-bus-amqp 52 | 53 | 54 | 55 | 56 | 57 | 58 | de.codecentric 59 | spring-boot-admin-starter-client 60 | ${spring-boot-admin-starter-client.version} 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.apache.httpcomponents 68 | httpclient 69 | 70 | 71 | 76 | 77 | 78 | io.github.openfeign 79 | feign-okhttp 80 | 81 | 82 | 83 | io.github.openfeign.form 84 | feign-form 85 | ${feign-form.version} 86 | 87 | 88 | io.github.openfeign.form 89 | feign-form-spring 90 | ${feign-form-spring.version} 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/java/com/lynchj/demoapizuul/filters/ModifyRequestEntityFilter.java: -------------------------------------------------------------------------------- 1 | package com.lynchj.demoapizuul.filters; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.lynchj.demoapizuul.constants.SessionContants; 5 | import com.netflix.zuul.ZuulFilter; 6 | import com.netflix.zuul.context.RequestContext; 7 | import com.netflix.zuul.exception.ZuulException; 8 | import com.netflix.zuul.http.HttpServletRequestWrapper; 9 | import com.netflix.zuul.http.ServletInputStreamWrapper; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.apache.commons.lang3.exception.ExceptionUtils; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.util.StreamUtils; 15 | 16 | import javax.servlet.ServletInputStream; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | import java.net.URLDecoder; 20 | import java.nio.charset.Charset; 21 | 22 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; 23 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 24 | 25 | /** 26 | * @Author:大漠知秋 27 | * @Description:修改请求体内容 28 | * @CreateDate:4:35 PM 2018/10/31 29 | */ 30 | @Component 31 | @Slf4j 32 | public class ModifyRequestEntityFilter extends ZuulFilter { 33 | 34 | @Override 35 | public String filterType() { 36 | return PRE_TYPE; 37 | } 38 | 39 | @Override 40 | public int filterOrder() { 41 | return PRE_DECORATION_FILTER_ORDER + 1; 42 | } 43 | 44 | @Override 45 | public boolean shouldFilter() { 46 | return true; 47 | } 48 | 49 | @Override 50 | public Object run() throws ZuulException { 51 | RequestContext ctx = RequestContext.getCurrentContext(); 52 | try { 53 | // 编码格式 54 | String charset = ctx.getRequest().getCharacterEncoding(); 55 | InputStream in = (InputStream) ctx.get("requestEntity"); 56 | if (null == in) { 57 | in = ctx.getRequest().getInputStream(); 58 | } 59 | String requestEntityStr = StreamUtils.copyToString(in, Charset.forName(charset)); 60 | if (StringUtils.isNotBlank(requestEntityStr)) { 61 | requestEntityStr = URLDecoder.decode(requestEntityStr, charset); 62 | JSONObject requestEntityJson = JSONObject.parseObject(requestEntityStr); 63 | // 新增参数 64 | requestEntityJson.put("newParam", "1111111"); 65 | byte[] requestEntityBytes = requestEntityJson.toJSONString().getBytes(charset); 66 | ctx.setRequest(new HttpServletRequestWrapper(ctx.getRequest()) { 67 | @Override 68 | public ServletInputStream getInputStream() throws IOException { 69 | return new ServletInputStreamWrapper(requestEntityBytes); 70 | } 71 | 72 | @Override 73 | public int getContentLength() { 74 | return requestEntityBytes.length; 75 | } 76 | 77 | @Override 78 | public long getContentLengthLong() { 79 | return requestEntityBytes.length; 80 | } 81 | }); 82 | } 83 | } catch (Exception e) { 84 | // 用来给后面的 Filter 标识,是否继续执行 85 | ctx.set(SessionContants.LOGIC_IS_SUCCESS, false); 86 | // 返回信息 87 | ctx.setResponseBody(String.format(SessionContants.ERROR_RESPONSE_BODY, "修改请求体出错")); 88 | // 对该请求禁止路由,禁止访问下游服务 89 | ctx.setSendZuulResponse(false); 90 | log.error("【修改请求体 Filter】-出错了:{}", ExceptionUtils.getStackTrace(e)); 91 | } 92 | 93 | ctx.addZuulRequestHeader("newHeader", "111111"); 94 | return null; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /demo-order/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-order 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo-order 12 | 演示样例 Order 服务 13 | 14 | 15 | com.lynchj 16 | demo-spring-cloud-finchley 17 | 0.0.1-SNAPSHOT 18 | ../pom.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-openfeign 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-netflix-ribbon 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-netflix-hystrix 42 | 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-config-client 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-bus-amqp 52 | 53 | 54 | 55 | 56 | 57 | 58 | de.codecentric 59 | spring-boot-admin-starter-client 60 | ${spring-boot-admin-starter-client.version} 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.apache.httpcomponents 68 | httpclient 69 | 70 | 71 | 76 | 77 | 78 | io.github.openfeign 79 | feign-okhttp 80 | 81 | 82 | 83 | io.github.openfeign.form 84 | feign-form 85 | ${feign-form.version} 86 | 87 | 88 | io.github.openfeign.form 89 | feign-form-spring 90 | ${feign-form-spring.version} 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /demo-eureka-server/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 8761 4 | # SSL 配置 5 | ssl: 6 | # 开启 SSL 认证 7 | enabled: false 8 | # 证书别名 9 | key-alias: eurekaserver 10 | # 证书存放路径 11 | key-store: classpath:EurekaServer.p12 12 | # 证书密码 13 | key-store-password: 123456 14 | # 存储类型 15 | key-store-type: PKCS12 16 | # Undertow 服务器优化 17 | undertow: 18 | # 设置 IO 线程数,它主要执行非阻塞的任务, 19 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 20 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 21 | io-threads: 12 22 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 23 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 24 | # 默认值:IO 线程数 * 8 25 | worker-threads: 96 26 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 27 | direct-buffers: true 28 | # 每块 buffer 的空间大小,空间越小利用越充分, 29 | # 不要设置太大,以免影响其他应用,合适即可 30 | buffer-size: 1024 31 | 32 | spring: 33 | application: 34 | # Spring Boot 项目实例名称 35 | name: demo-eureka-server 36 | # 开启安全控制 37 | security: 38 | user: 39 | # 用户名 40 | name: eureka-server 41 | # 密码 42 | password: 8e9lx7LuP3436gfsg 43 | boot: 44 | admin: 45 | client: 46 | # 基于 Spring Boot 项目的监控地址 47 | url: 'http://localhost:1700' 48 | instance: 49 | service-base-url: 'http://localhost:1700' 50 | 51 | ### 日志配置 52 | logback: 53 | spring: 54 | level: INFO 55 | project: 56 | level: INFO 57 | 58 | ### 端点控制 59 | management: 60 | endpoints: 61 | web: 62 | exposure: 63 | # 开启指定端点、所有端点 64 | include: 'health' 65 | endpoint: 66 | health: 67 | # 总是表示详细信息的显示 68 | show-details: always 69 | 70 | eureka: 71 | instance: 72 | # 主机名 73 | hostname: localhost 74 | # 使用 ip 注册到注册中心实例化 75 | prefer-ip-address: true 76 | # 安全端口 77 | secure-port: ${server.port} 78 | # 指示是否应为流量启用安全端口 79 | secure-port-enabled: true 80 | # 是否开启非安全端口 81 | non-secure-port-enabled: false 82 | home-page-url: https://${eureka.instance.hostname}:${server.port}/ 83 | status-page-url: https://${eureka.instance.hostname}:${server.port}/actuator/info 84 | health-check-url: https://${eureka.instance.hostname}:${server.port}/actuator/health 85 | client: 86 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 87 | secure-port-enabled: false 88 | ssl: 89 | # 开启 Https 注册到注册中心使用的证书 90 | key-store: EurekaClient.p12 91 | # 开启 Https 注册到注册中心使用的证书密码 92 | key-store-password: 123456 93 | # 此实例是否从注册中心获取注册信息 94 | fetch-registry: false 95 | # 是否将此实例注册到注册中心 96 | register-with-eureka: false 97 | # 注册地址 98 | service-url: 99 | # 默认注册分区地址 100 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 101 | server: 102 | # 同步为空时,等待时间 103 | wait-time-in-ms-when-sync-empty: 0 104 | # 是否开启自我保护机制 105 | ## 在分布式系统设计里头,通常需要对应用实例的存活进行健康检查,这里比较关键的问题就是要处理好网络偶尔抖动或短暂不可用时造成的误判。另外Eureka Server端与Client端之间如果出现网络分区问题,在极端情况下可能会使得Eureka Server清空部分服务的实例列表,这个将严重影响到Eureka server的 availibility属性。因此Eureka server引入了SELF PRESERVATION机制。 106 | ## Eureka client端与Server端之间有个租约,Client要定时发送心跳来维持这个租约,表示自己还存活着。 Eureka通过当前注册的实例数,去计算每分钟应该从应用实例接收到的心跳数,如果最近一分钟接收到的续约的次数小于指定阈值的话,则关闭租约失效剔除,禁止定时任务剔除失效的实例,从而保护注册信息。 107 | # 此处关闭可以防止问题(测试环境可以设置为false):Eureka server由于开启并引入了SELF PRESERVATION模式,导致registry的信息不会因为过期而被剔除掉,直到退出SELF PRESERVATION模式才能剔除。 108 | enable-self-preservation: false 109 | # 指定 Eviction Task 定时任务的调度频率,用于剔除过期的实例,此处未使用默认频率,频率为:5/秒,默认为:60/秒 110 | # 有效防止的问题是:应用实例异常挂掉,没能在挂掉之前告知Eureka server要下线掉该服务实例信息。这个就需要依赖Eureka server的EvictionTask去剔除。 111 | eviction-interval-timer-in-ms: 5000 112 | # 设置read Write CacheMap的expire After Write参数,指定写入多长时间后过期 113 | # 有效防止的问题是:应用实例下线时有告知Eureka server下线,但是由于Eureka server的REST API有response cache,因此需要等待缓存过期才能更新 114 | response-cache-auto-expiration-in-seconds: 60 115 | # 此处不开启缓存,上方配置开启一个即可 116 | # use-read-only-response-cache: false 117 | # 指定每分钟需要收到的续约次数的阈值,默认值就是:0.85 118 | renewal-percent-threshold: 0.85 119 | # 续约频率提高,默认:30 120 | leaseRenewalIntervalInseconds: 10 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lynchj 7 | demo-spring-cloud-finchley 8 | 0.0.1-SNAPSHOT 9 | pom 10 | 11 | demo-spring-cloud-finchley 12 | 演示样例 Spring Cloud Finchley 父级项目 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.6.RELEASE 18 | 19 | 20 | 21 | 22 | demo-eureka-server 23 | demo-order 24 | demo-goods 25 | demo-hystrix-dashboard 26 | demo-admin-server 27 | demo-api-zuul 28 | demo-config-server 29 | 30 | 31 | 32 | UTF-8 33 | UTF-8 34 | 1.8 35 | Finchley.RELEASE 36 | 1.2.47 37 | 8.18.0 38 | 3.0.3 39 | 3.0.3 40 | 2.0.4 41 | 2.0.4 42 | 2.1.0 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-dependencies 50 | ${spring-cloud.version} 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-web 66 | 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-starter-tomcat 71 | 72 | 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-test 78 | test 79 | 80 | 81 | 82 | org.springframework.boot 83 | spring-boot-starter-actuator 84 | 85 | 86 | 87 | org.springframework.boot 88 | spring-boot-starter-undertow 89 | 90 | 91 | 92 | 93 | 94 | 95 | org.projectlombok 96 | lombok 97 | 98 | 99 | 100 | org.slf4j 101 | slf4j-api 102 | 103 | 104 | ch.qos.logback 105 | logback-core 106 | 107 | 108 | ch.qos.logback 109 | logback-classic 110 | 111 | 112 | org.slf4j 113 | log4j-over-slf4j 114 | 115 | 116 | 117 | com.alibaba 118 | fastjson 119 | ${alibaba-fastjson.version} 120 | 121 | 122 | 123 | org.apache.commons 124 | commons-lang3 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | ${basedir}/src/main/resources 135 | 136 | **/*.p12 137 | **/*.yml 138 | **/*.xml 139 | 140 | false 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /demo-goods/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 11200 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-goods 24 | boot: 25 | admin: 26 | client: 27 | # 基于 Spring Boot 项目的监控地址 28 | url: 'http://localhost:1700' 29 | instance: 30 | service-base-url: 'http://localhost:1700' 31 | cloud: 32 | config: 33 | ## 自定义配置项 34 | auto-refresh-config: 35 | # 是否开启自动刷新配置 36 | enabled: false 37 | # 间隔时间,单位:ms 38 | refresh-interval: 5000 39 | # 分支,默认:master 40 | label: master 41 | # 用于获取远程属性的名称 42 | name: demo-spring-cloud 43 | # 获取远程配置时使用的配置文件属于什么环境 44 | profile: dev 45 | # 链接远程服务器时要使用的用户名(HTTP Basic),如果需要 46 | username: config-server 47 | # 链接远程服务器时要使用的密码(HTTP Basic),如果需要 48 | password: 8e9lx7LuP3436gfsg 49 | # 服务发现 50 | discovery: 51 | # 是否开启服务发现 52 | enabled: true 53 | # 配置中心 实例名 54 | service-id: demo-config-server 55 | # RabbitMQ 配置 56 | rabbitmq: 57 | # 地址 58 | host: localhost 59 | # 端口 60 | port: 5672 61 | # 用户名 62 | username: admin 63 | # 密码 64 | password: nS8KiyIu0Y7LGbvE 65 | 66 | ### 日志配置 67 | logback: 68 | spring: 69 | level: INFO 70 | project: 71 | level: INFO 72 | 73 | ### 端点控制 74 | management: 75 | endpoints: 76 | web: 77 | exposure: 78 | # 开启指定端点、所有端点 79 | include: '*' 80 | endpoint: 81 | health: 82 | # 总是表示详细信息的显示 83 | show-details: always 84 | 85 | ### 注册中心配置 86 | eureka: 87 | instance: 88 | # 主机名 89 | hostname: localhost 90 | # 使用 ip 注册到注册中心实例化 91 | prefer-ip-address: true 92 | client: 93 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 94 | secure-port-enabled: false 95 | ssl: 96 | # 开启 Https 注册到注册中心使用的证书 97 | key-store: EurekaClient.p12 98 | # 开启 Https 注册到注册中心使用的证书密码 99 | key-store-password: 123456 100 | security: 101 | user: 102 | name: eureka-server 103 | password: 8e9lx7LuP3436gfsg 104 | # Spring Cloud Eureka 注册中心地址 105 | service-url: 106 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 107 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 108 | registry-fetch-interval-seconds: 30 109 | 110 | ### Feign 配置 111 | feign: 112 | compression: 113 | request: 114 | # 开启请求压缩 115 | enabled: true 116 | # 配置压缩的 MIME TYPE 117 | mime-types: text/xml,application/xml,application/json 118 | # 配置压缩数据大小的下限 119 | min-request-size: 2048 120 | response: 121 | # 开启响应压缩 122 | enabled: true 123 | # 是否开启断路器(熔断器) 124 | hystrix: 125 | enabled: true 126 | httpclient: 127 | # 是否开启 Http Client 128 | enabled: false 129 | # # 最大连接数,默认:200 130 | # max-connections: 200 131 | # # 最大路由,默认:50 132 | # max-connections-per-route: 50 133 | # # 连接超时,默认:2000/毫秒 134 | # connection-timeout: 2000 135 | # # 生存时间,默认:900L 136 | ## time-to-live: 900 137 | # # 响应超时的时间单位,默认:TimeUnit.SECONDS 138 | ## timeToLiveUnit: SECONDS 139 | okhttp: 140 | enabled: true 141 | 142 | ### Feign Logger Level 配置 143 | logging: 144 | level: 145 | com.lynchj.demogoods.feign.OrderFeign: debug 146 | 147 | ### Ribbon 配置 148 | ribbon: 149 | # http建立socket超时时间,毫秒 150 | ConnectTimeout: 2000 151 | # http读取响应socket超时时间 152 | ReadTimeout: 8000 153 | # 同一台实例最大重试次数,不包括首次调用 154 | MaxAutoRetries: 0 155 | # 重试负载均衡其他的实例最大重试次数,不包括首次server 156 | MaxAutoRetriesNextServer: 0 157 | # 是否所有操作都重试,POST请求注意多次提交错误。 158 | # 默认false,设定为false的话,只有get请求会重试 159 | OkToRetryOnAllOperations: true 160 | # 饥饿加载 161 | eager-load: 162 | # 是否开启饥饿加载 163 | enabled: true 164 | # 饥饿加载的服务 165 | clients: demo-order,demo-product 166 | # Eureka 配置 167 | # eureka: 168 | # # 禁止使用 Eureka 获取负载服务列表 169 | # enabled: false 170 | 171 | ### 针对单个服务的 Ribbon 配置 172 | demo-order: 173 | ribbon: 174 | # 基于配置文件形式的 针对单个服务的 Ribbon 负载均衡策略 175 | NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule 176 | # http建立socket超时时间,毫秒 177 | ConnectTimeout: 2000 178 | # http读取响应socket超时时间 179 | ReadTimeout: 5000 180 | # 同一台实例最大重试次数,不包括首次调用 181 | MaxAutoRetries: 0 182 | # 重试负载均衡其他的实例最大重试次数,不包括首次server 183 | MaxAutoRetriesNextServer: 2 184 | # 是否所有操作都重试,POST请求注意多次提交错误。 185 | # 默认false,设定为false的话,只有get请求会重试 186 | OkToRetryOnAllOperations: true 187 | # 手动指定 Ribbon 服务列表 188 | # listOfServers: http://localhost:11200,http://localhost:11201 189 | 190 | ### Hystrix 配置 191 | hystrix: 192 | # 这样将会自动配置一个 Hystrix 并发策略插件的 hook,这个 hook 会将 SecurityContext 从主线程传输到 Hystrix 的命令。 193 | # 因为 Hystrix 不允许注册多个 Hystrix 策略,所以可以声明 HystrixConcurrencyStrategy 194 | # 为一个 Spring bean 来实现扩展。Spring Cloud 会在 Spring 的上下文中查找你的实现,并将其包装在自己的插件中。 195 | shareSecurityContext: true 196 | command: 197 | default: 198 | # 断路器配置 199 | circuitBreaker: 200 | # 当在配置时间窗口内达到此数量的失败后,进行断路。默认:20个 201 | requestVolumeThreshold: 20 202 | # 出错百分比阈值,当达到此阈值后,开始断路。默认:50% 203 | errorThresholdpercentage: 50 204 | # 触发短路的时间值,当该值设为5000时,则当触发 circuit break 后的5000毫秒内都会拒绝request 205 | # 也就是5000毫秒后才会关闭circuit。默认:5000 206 | sleepWindowInMilliseconds: 5000 207 | # 强制打开断路器,如果打开这个开关,那么拒绝所有request,默认false 208 | forceOpen: false 209 | # 强制关闭断路器 如果这个开关打开,circuit将一直关闭且忽略,默认false 210 | forceClosed: false 211 | execution: 212 | # 熔断器配置 213 | isolation: 214 | # 隔离策略,线程池隔离机制,如果不配置,默认配置:THREAD 215 | strategy: THREAD 216 | thread: 217 | # 熔断器超时时间,默认:1000/毫秒 218 | timeoutInMilliseconds: 18000 219 | # 超时时是否立马中断 220 | interruptOnTimeout: true 221 | semaphore: 222 | # 信号量请求数,当设置为信号量隔离策略时,设置最大允许的请求数 223 | maxConcurrentRequests: 10 224 | # timeout: 225 | # # 禁用熔断器超时时间,不推荐 226 | # enabled: false 227 | threadpool: 228 | defalut: 229 | # 当使用线程隔离策略时,线程池的核心大小 230 | coreSize: 20 231 | # 当 Hystrix 隔离策略为线程池隔离模式时,最大线程池大小的配置,在 `1.5.9` 版本中还需要配置 `allowMaximumSizeToDivergeFromCoreSize` 为 true 232 | maximumSize: 30 233 | # 此属性语序配置的 maximumSize 生效 234 | allowMaximumSizeToDivergeFromCoreSize: true -------------------------------------------------------------------------------- /demo-order/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 11100 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-order 24 | boot: 25 | admin: 26 | client: 27 | # 基于 Spring Boot 项目的监控地址 28 | url: 'http://localhost:1700' 29 | instance: 30 | service-base-url: 'http://localhost:1700' 31 | cloud: 32 | config: 33 | ## 自定义配置项 34 | auto-refresh-config: 35 | # 是否开启自动刷新配置 36 | enabled: false 37 | # 间隔时间,单位:ms 38 | refresh-interval: 5000 39 | # 分支,默认:master 40 | label: master 41 | # 用于获取远程属性的名称 42 | name: demo-spring-cloud 43 | # 获取远程配置时使用的配置文件属于什么环境 44 | profile: dev 45 | # 链接远程服务器时要使用的用户名(HTTP Basic),如果需要 46 | username: config-server 47 | # 链接远程服务器时要使用的密码(HTTP Basic),如果需要 48 | password: 8e9lx7LuP3436gfsg 49 | # 服务发现 50 | discovery: 51 | # 是否开启服务发现 52 | enabled: true 53 | # 配置中心 实例名 54 | service-id: demo-config-server 55 | # RabbitMQ 配置 56 | rabbitmq: 57 | # 地址 58 | host: localhost 59 | # 端口 60 | port: 5672 61 | # 用户名 62 | username: admin 63 | # 密码 64 | password: nS8KiyIu0Y7LGbvE 65 | 66 | ### 日志配置 67 | logback: 68 | spring: 69 | level: INFO 70 | project: 71 | level: INFO 72 | 73 | ### 端点控制 74 | management: 75 | endpoints: 76 | web: 77 | exposure: 78 | # 开启指定端点、所有端点 79 | include: '*' 80 | endpoint: 81 | health: 82 | # 总是表示详细信息的显示 83 | show-details: always 84 | 85 | ### 注册中心配置 86 | eureka: 87 | instance: 88 | # 主机名 89 | hostname: localhost 90 | # 使用 ip 注册到注册中心实例化 91 | prefer-ip-address: true 92 | # 自定义元数据 93 | metadata-map: 94 | # host 标识 95 | host-mark: running-host 96 | client: 97 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 98 | secure-port-enabled: false 99 | ssl: 100 | # 开启 Https 注册到注册中心使用的证书 101 | key-store: EurekaClient.p12 102 | # 开启 Https 注册到注册中心使用的证书密码 103 | key-store-password: 123456 104 | security: 105 | user: 106 | name: eureka-server 107 | password: 8e9lx7LuP3436gfsg 108 | # Spring Cloud Eureka 注册中心地址 109 | service-url: 110 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 111 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 112 | registry-fetch-interval-seconds: 30 113 | # 当 Eureka Server 不可用时,这时就获取不到 注册列表,当从此类进行获取注册列表 114 | backup-registry-impl: com.lynchj.demoorder.config.StaticBackupRegistryListConfiguration 115 | 116 | ### Feign 配置 117 | feign: 118 | compression: 119 | request: 120 | # 开启请求压缩 121 | enabled: true 122 | # 配置压缩的 MIME TYPE 123 | mime-types: text/xml,application/xml,application/json 124 | # 配置压缩数据大小的下限 125 | min-request-size: 2048 126 | response: 127 | # 开启响应压缩 128 | enabled: true 129 | # 是否开启断路器(熔断器) 130 | hystrix: 131 | enabled: true 132 | httpclient: 133 | # 是否开启 Http Client 134 | enabled: false 135 | # # 最大连接数,默认:200 136 | # max-connections: 200 137 | # # 最大路由,默认:50 138 | # max-connections-per-route: 50 139 | # # 连接超时,默认:2000/毫秒 140 | # connection-timeout: 2000 141 | # # 生存时间,默认:900L 142 | ## time-to-live: 900 143 | # # 响应超时的时间单位,默认:TimeUnit.SECONDS 144 | ## timeToLiveUnit: SECONDS 145 | okhttp: 146 | enabled: true 147 | 148 | ### Feign Logger Level 配置 149 | logging: 150 | level: 151 | com.lynchj.demoorder.feign.GoodsFeign: debug 152 | 153 | ### Ribbon 配置 154 | ribbon: 155 | # http建立socket超时时间,毫秒 156 | ConnectTimeout: 2000 157 | # http读取响应socket超时时间 158 | ReadTimeout: 8000 159 | # 同一台实例最大重试次数,不包括首次调用 160 | MaxAutoRetries: 0 161 | # 重试负载均衡其他的实例最大重试次数,不包括首次server 162 | MaxAutoRetriesNextServer: 0 163 | # 是否所有操作都重试,POST请求注意多次提交错误。 164 | # 默认false,设定为false的话,只有get请求会重试 165 | OkToRetryOnAllOperations: true 166 | # 饥饿加载 167 | eager-load: 168 | # 是否开启饥饿加载 169 | enabled: true 170 | # 饥饿加载的服务 171 | clients: demo-goods,demo-product 172 | # Eureka 配置 173 | # eureka: 174 | # # 禁止使用 Eureka 获取负载服务列表 175 | # enabled: false 176 | 177 | ### 针对单个服务的 Ribbon 配置 178 | demo-goods: 179 | ribbon: 180 | # 基于配置文件形式的 针对单个服务的 Ribbon 负载均衡策略 181 | NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule 182 | # http建立socket超时时间,毫秒 183 | ConnectTimeout: 2000 184 | # http读取响应socket超时时间 185 | ReadTimeout: 5000 186 | # 同一台实例最大重试次数,不包括首次调用 187 | MaxAutoRetries: 0 188 | # 重试负载均衡其他的实例最大重试次数,不包括首次server 189 | MaxAutoRetriesNextServer: 2 190 | # 是否所有操作都重试,POST请求注意多次提交错误。 191 | # 默认false,设定为false的话,只有get请求会重试 192 | OkToRetryOnAllOperations: true 193 | # 手动指定 Ribbon 服务列表 194 | # listOfServers: http://localhost:11200,http://localhost:11201 195 | 196 | ### Hystrix 配置 197 | hystrix: 198 | # 这样将会自动配置一个 Hystrix 并发策略插件的 hook,这个 hook 会将 SecurityContext 从主线程传输到 Hystrix 的命令。 199 | # 因为 Hystrix 不允许注册多个 Hystrix 策略,所以可以声明 HystrixConcurrencyStrategy 200 | # 为一个 Spring bean 来实现扩展。Spring Cloud 会在 Spring 的上下文中查找你的实现,并将其包装在自己的插件中。 201 | shareSecurityContext: true 202 | command: 203 | default: 204 | # 断路器配置 205 | circuitBreaker: 206 | # 当在配置时间窗口内达到此数量的失败后,进行断路。默认:20个 207 | requestVolumeThreshold: 20 208 | # 出错百分比阈值,当达到此阈值后,开始断路。默认:50% 209 | errorThresholdpercentage: 50 210 | # 触发短路的时间值,当该值设为5000时,则当触发 circuit break 后的5000毫秒内都会拒绝request 211 | # 也就是5000毫秒后才会关闭circuit。默认:5000 212 | sleepWindowInMilliseconds: 5000 213 | # 强制打开断路器,如果打开这个开关,那么拒绝所有request,默认false 214 | forceOpen: false 215 | # 强制关闭断路器 如果这个开关打开,circuit将一直关闭且忽略,默认false 216 | forceClosed: false 217 | execution: 218 | # 熔断器配置 219 | isolation: 220 | # 隔离策略,线程池隔离机制,如果不配置,默认配置:THREAD 221 | strategy: THREAD 222 | thread: 223 | # 熔断器超时时间,默认:1000/毫秒 224 | timeoutInMilliseconds: 18000 225 | # 超时时是否立马中断 226 | interruptOnTimeout: true 227 | semaphore: 228 | # 信号量请求数,当设置为信号量隔离策略时,设置最大允许的请求数 229 | maxConcurrentRequests: 10 230 | # timeout: 231 | # # 禁用熔断器超时时间,不推荐 232 | # enabled: false 233 | threadpool: 234 | defalut: 235 | # 当使用线程隔离策略时,线程池的核心大小 236 | coreSize: 20 237 | # 当 Hystrix 隔离策略为线程池隔离模式时,最大线程池大小的配置,在 `1.5.9` 版本中还需要配置 `allowMaximumSizeToDivergeFromCoreSize` 为 true 238 | maximumSize: 30 239 | # 此属性语序配置的 maximumSize 生效 240 | allowMaximumSizeToDivergeFromCoreSize: true 241 | -------------------------------------------------------------------------------- /demo-api-zuul/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 项目端口号 3 | port: 18000 4 | # Undertow 服务器优化 5 | undertow: 6 | # 设置 IO 线程数,它主要执行非阻塞的任务, 7 | # 它们会负责多个连接,默认设置每个 CPU 核心有一个线程。 8 | # 不要设置过大,如果过大,启动项日会报错:打开文件数过多 9 | io-threads: 12 10 | # 阳塞任务线程数,当执行类似 Servlet 请求阻塞 IO 操作, 11 | # Undertow 会从这个线程池中取得线程。它的值设置取决于系统线程执行任务的阻塞系数, 12 | # 默认值:IO 线程数 * 8 13 | worker-threads: 96 14 | # 是否分配直接内存(NIO 直接分配的是堆外内存) 15 | direct-buffers: true 16 | # 每块 buffer 的空间大小,空间越小利用越充分, 17 | # 不要设置太大,以免影响其他应用,合适即可 18 | buffer-size: 1024 19 | 20 | spring: 21 | application: 22 | # Spring Boot 项目实例名称 23 | name: demo-api-zuul 24 | boot: 25 | admin: 26 | client: 27 | # 基于 Spring Boot 项目的监控地址 28 | url: 'http://localhost:1700' 29 | instance: 30 | service-base-url: 'http://localhost:1700' 31 | cloud: 32 | loadbalancer: 33 | retry: 34 | # 重试开关,默认:true 35 | enabled: true 36 | config: 37 | ## 自定义配置项 38 | auto-refresh-config: 39 | # 是否开启自动刷新配置 40 | enabled: false 41 | # 间隔时间,单位:ms 42 | refresh-interval: 5000 43 | # 分支,默认:master 44 | label: master 45 | # 用于获取远程属性的名称 46 | name: demo-spring-cloud 47 | # 获取远程配置时使用的配置文件属于什么环境 48 | profile: dev 49 | # 链接远程服务器时要使用的用户名(HTTP Basic),如果需要 50 | username: config-server 51 | # 链接远程服务器时要使用的密码(HTTP Basic),如果需要 52 | password: 8e9lx7LuP3436gfsg 53 | # 服务发现 54 | discovery: 55 | # 是否开启服务发现 56 | enabled: true 57 | # 配置中心 实例名 58 | service-id: demo-config-server 59 | servlet: 60 | multipart: 61 | # 是否启用分段上传支持,默认:true 62 | enabled: true 63 | # 最大单个文件大小。值可以使用后缀“MB”或“KB”分别表示兆字节或千字节。默认:1MB 64 | max-file-size: 20MB 65 | # 最大请求大小。值可以使用后缀“MB”或“KB”分别表示兆字节或千字节。默认:10MB 66 | max-request-size: 100MB 67 | # 文件写入磁盘的阈值,当上传文件达到 1M 事开始写入磁盘。值可以使用后缀“MB”或“KB”分别表示兆字节或千字节。默认:0 68 | file-size-threshold: 1MB 69 | # 上传文件的临时位置 70 | location: / 71 | # RabbitMQ 配置 72 | rabbitmq: 73 | # 地址 74 | host: localhost 75 | # 端口 76 | port: 5672 77 | # 用户名 78 | username: admin 79 | # 密码 80 | password: nS8KiyIu0Y7LGbvE 81 | 82 | ### 日志配置 83 | logback: 84 | spring: 85 | level: INFO 86 | project: 87 | level: INFO 88 | 89 | ### 端点控制 90 | management: 91 | endpoints: 92 | web: 93 | exposure: 94 | # 开启指定端点、所有端点 95 | include: 'hystrix.stream,routes,filters,info,health' 96 | endpoint: 97 | health: 98 | show-details: always 99 | 100 | ### 注册中心配置 101 | eureka: 102 | instance: 103 | # 主机名 104 | hostname: localhost 105 | # 使用 ip 注册到注册中心实例化 106 | prefer-ip-address: true 107 | client: 108 | # 是否开启 Https 注册到注册中心,与高可用的配置中心有冲突 109 | secure-port-enabled: false 110 | ssl: 111 | # 开启 Https 注册到注册中心使用的证书 112 | key-store: EurekaClient.p12 113 | # 开启 Https 注册到注册中心使用的证书密码 114 | key-store-password: 123456 115 | security: 116 | user: 117 | name: eureka-server 118 | password: 8e9lx7LuP3436gfsg 119 | # Spring Cloud Eureka 注册中心地址 120 | service-url: 121 | defaultZone: http://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/ 122 | # 针对新服务上线, Eureka client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,默认:30秒 123 | registry-fetch-interval-seconds: 30 124 | # 当 Eureka Server 不可用时,这时就获取不到 注册列表,当从此类进行获取注册列表 125 | backup-registry-impl: com.lynchj.demoapizuul.config.StaticBackupRegistryListConfiguration 126 | 127 | ### Ribbon 配置 128 | ribbon: 129 | # http建立socket超时时间,毫秒 130 | ConnectTimeout: 2000 131 | # http读取响应socket超时时间 132 | ReadTimeout: 8000 133 | # 同一台实例最大重试次数,不包括首次调用 134 | MaxAutoRetries: 0 135 | # 重试负载均衡其他的实例最大重试次数,不包括首次server 136 | MaxAutoRetriesNextServer: 1 137 | # 是否所有操作都重试,POST请求注意多次提交错误。 138 | # 默认false,设定为false的话,只有get请求会重试 139 | OkToRetryOnAllOperations: true 140 | httpclient: 141 | # 关闭 httpclient 支持 142 | enabled: false 143 | okhttp: 144 | # 开启 okhttp 支持 145 | enabled: true 146 | 147 | ### Hystrix 配置 148 | hystrix: 149 | # 这样将会自动配置一个 Hystrix 并发策略插件的 hook,这个 hook 会将 SecurityContext 从主线程传输到 Hystrix 的命令。 150 | # 因为 Hystrix 不允许注册多个 Hystrix 策略,所以可以声明 HystrixConcurrencyStrategy 151 | # 为一个 Spring bean 来实现扩展。Spring Cloud 会在 Spring 的上下文中查找你的实现,并将其包装在自己的插件中。 152 | shareSecurityContext: true 153 | command: 154 | default: 155 | # 断路器配置 156 | circuitBreaker: 157 | # 当在配置时间窗口内达到此数量的失败后,进行断路。默认:20个 158 | requestVolumeThreshold: 20 159 | # 出错百分比阈值,当达到此阈值后,开始断路。默认:50% 160 | errorThresholdpercentage: 50 161 | # 触发短路的时间值,当该值设为5000时,则当触发 circuit break 后的5000毫秒内都会拒绝request 162 | # 也就是5000毫秒后才会关闭circuit。默认:5000 163 | sleepWindowInMilliseconds: 5000 164 | # 强制打开断路器,如果打开这个开关,那么拒绝所有request,默认false 165 | forceOpen: false 166 | # 强制关闭断路器 如果这个开关打开,circuit将一直关闭且忽略,默认false 167 | forceClosed: false 168 | execution: 169 | # 熔断器配置 170 | isolation: 171 | # 隔离策略,线程池隔离机制,如果不配置,默认配置:THREAD 172 | strategy: THREAD 173 | thread: 174 | # 熔断器超时时间,默认:1000/毫秒 175 | timeoutInMilliseconds: 20000 176 | # 超时时是否立马中断 177 | interruptOnTimeout: true 178 | semaphore: 179 | # 信号量请求数,当设置为信号量隔离策略时,设置最大允许的请求数 180 | maxConcurrentRequests: 10 181 | # timeout: 182 | # # 禁用熔断器超时时间,不推荐 183 | # enabled: false 184 | threadpool: 185 | defalut: 186 | # 当使用线程隔离策略时,线程池的核心大小 187 | coreSize: 20 188 | # 当 Hystrix 隔离策略为线程池隔离模式时,最大线程池大小的配置,在 `1.5.9` 版本中还需要配置 `allowMaximumSizeToDivergeFromCoreSize` 为 true 189 | maximumSize: 30 190 | # 此属性语序配置的 maximumSize 生效 191 | allowMaximumSizeToDivergeFromCoreSize: true 192 | 193 | ### 网关配置 194 | zuul: 195 | # 路由信息配置 196 | routes: 197 | # 针对某个服务的配置,可自定义 198 | demo-order: 199 | # 访问的路径,此处要以 '/do/' 开头 200 | path: /do/** 201 | # 后端服务的实例 Id。 202 | # 意思:以 '/do/' 开头的请求,都会向后端服务 'demo-order' 进行转发 203 | serviceId: demo-order 204 | # 剥夺前缀,此配置是针对上方 'path' 配置的项 205 | # 为 true 的情况下:向后端转发之后是不会携带 '/do' 的。为 false 则相反 206 | stripPrefix: true 207 | # 不向后端服务传递的敏感头信息 208 | sensitiveHeaders: Cookie,Set-Cookie,Authorization 209 | demo-local: 210 | # 访问的路径,此处要以 '/do/' 开头 211 | path: /local/** 212 | # 访问的 url,forward:向本地转发 213 | url: forward:/local 214 | # 忽略的服务,有些后端服务是不需要让网管代理的,防止服务侵入 215 | ignored-services: service-a,service-b,config-server 216 | # 忽略的接口,屏蔽接口 217 | ignored-patterns: /**/div/** 218 | # 此处解决后端服务重定向导致用户浏览的 host 变成 后端服务的 host 问题 219 | add-host-header: true 220 | # 开启重试机制,结合 Ribbon(默认集成),只需配置即可,慎用,有些接口要考虑到幂等性,D 版之后默认:false 221 | retryable: true 222 | # 路由模式更改为 线程池隔离模式 223 | ribbon-isolation-strategy: THREAD 224 | thread-pool: 225 | # 每个路由都有自己的线程池 226 | use-separate-thread-pools: true 227 | # 指定一个线程池前缀方便调试 228 | thread-pool-key-prefix: apizuul 229 | host: 230 | # 连接超时,针对使用 url 路由的情况 231 | connect-timeout-millis: 2000 232 | # 响应超时,针对使用 url 路由的情况 233 | socket-timeout-millis: 8000 234 | # 最大连接数 235 | max-total-connections: 200 236 | # 最大路由数 237 | max-per-route-connections: 20 --------------------------------------------------------------------------------