├── README.md ├── eureka-client ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── eurekaclient │ │ │ ├── EurekaClientApplication.java │ │ │ ├── controller │ │ │ └── HelloController.java │ │ │ └── entity │ │ │ └── User.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── eurekaclient │ └── EurekaClientApplicationTests.java ├── eureka-server ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── eurekaserver │ │ │ └── EurekaServerApplication.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── eurekaserver │ └── EurekaServerApplicationTests.java ├── feign-consumer ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── feignconsumer │ │ │ ├── FeignConsumerApplication.java │ │ │ ├── controller │ │ │ └── ConsumerController.java │ │ │ ├── entity │ │ │ └── User.java │ │ │ └── service │ │ │ ├── ConsumerService.java │ │ │ └── ConsumerServiceFallback.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── feignconsumer │ └── FeignConsumerApplicationTests.java ├── hystrix-dashboard ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── hystrixdashboard │ │ │ └── HystrixDashboardApplication.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── hystrixdashboard │ └── HystrixDashboardApplicationTests.java ├── pom.xml ├── ribbon-consumer ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── ribbonconsumer │ │ │ ├── RibbonConsumerApplication.java │ │ │ ├── controller │ │ │ └── ConsumerController.java │ │ │ └── service │ │ │ └── ConsumerService.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── ribbonconsumer │ └── RibbonConsumerApplicationTests.java ├── service-zuul ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── caogen │ │ │ └── servicezuul │ │ │ ├── ServiceZuulApplication.java │ │ │ └── filter │ │ │ └── AccessFilter.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── caogen │ └── servicezuul │ └── ServiceZuulApplicationTests.java └── turbine ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── caogen │ │ └── turbine │ │ └── TurbineApplication.java └── resources │ └── application.yml └── test └── java └── com └── caogen └── turbine └── TurbineApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # Java 微服务实践 - Spring Cloud 系列 2 | 3 | Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式环境中运行良好,包括开发人员自己的笔记本电脑,裸机数据中心,以及Cloud Foundry等托管平台。 4 | 5 | ## 特性 6 | 7 | Spring Cloud专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖。 8 | 9 | - 分布式/版本化配置 10 | 11 | - 服务注册和发现 12 | 13 | - 路由 14 | 15 | - service - to - service调用 16 | 17 | - 负载均衡 18 | 19 | - 断路器 20 | 21 | - 分布式消息传递 22 | 23 | ### [SpringCloud(一):服务注册中心Eureka](https://kcaogen.com/archives/springcloudeureka) 24 | 25 | Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能。Spring Cloud通过为Eureka增加了Spring Boot风格的自动化配置,我们只需通过简单引入依赖和注解配置就能让Spring Boot构建的微服务应用轻松地与Eureka服务治理体系进行整合。 26 | 27 | ### [SpringCloud(二):服务发现与消费](https://kcaogen.com/archives/springcloudserver) 28 | 29 | 服务的发现和消费实际上是两个行为,这两个行为要由不同的对象来完成:服务的发现由Eureka客户端来完成,而服务的消费由Ribbon来完成。Ribbo是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,服务端是否在线这些问题则交由Eureka去维护。 30 | 31 | ### [SpringCloud(三):断路器Hystrix](https://kcaogen.com/archives/springcloudhystrix) 32 | 33 | 在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式相互依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或者依赖服务自身的问题导致调用故障或延迟,而调用失败又会造成用户刷新页面并再次尝试调用,再加上其它服务调用,从而增加了服务器的负载,导致服务瘫痪,最终甚至会导致整个服务“雪崩”。 34 | 35 | ### [SpringCloud(四):Hystrix仪表板](https://kcaogen.com/archives/hystrixdashboard) 36 | 37 | Spring Cloud完美地整合了Hystrix的仪表板组件Hystrix Dashboard,它主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题,从而及时地采取应对措施。 38 | 39 | ### [SpringCloud(五):Turbine集群监控](https://kcaogen.com/archives/springcloudturbine) 40 | 41 | 看单个的Hystrix Dashboard的数据并没有什么多大的价值,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合。Hystrix Turbine的使用非常简单,只需要引入相应的依赖和加上注解和配置就可以了。 42 | 43 | ### [SpringCloud(六):服务消费者Feign 上](https://kcaogen.com/archives/springcloudfeign1) 44 | 45 | Spring Cloud Feign无参数绑定服务调用 46 | 47 | ### [SpringCloud(七):服务消费者Feign 中](https://kcaogen.com/archives/springcloudfeign2) 48 | 49 | Spring Cloud Feign有参数绑定服务调用 50 | 51 | ### [SpringCloud(八):服务消费者Feign 下](https://kcaogen.com/archives/springcloudfeign3) 52 | 53 | Hystrix提供的服务降级是服务容错的重要功能,由于Spring Cloud Feign在定义服务客户端的时候与Spring Cloud Ribbon有很大的差别,HystrixCommand定义被封装了起来,博客讲解Spring Cloud Feign的降级处理。 54 | 55 | ### [SpringCloud(九):API网关服务Zuul](https://kcaogen.com/archives/springcloudzuul) 56 | 57 | Spring Cloud Zuul 通过与 Spring Cloud Eureka 进行整合,将自身注册到 Eureka Server中,与Eureka,Ribbon,Hystrix等整合,同时从 Eureka 中获得了所有其它微服务的实例信息。这样的设计通过把网关和服务治理整合到一起,Spring Cloud Zuul可以获取到服务注册信息,结合Ribbon,Hystrix等更好的实现路由转发,负载均衡等功能。 58 | -------------------------------------------------------------------------------- /eureka-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | eureka-client 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | eureka-client 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-eureka 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-actuator 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-dependencies 51 | ${spring-cloud.version} 52 | pom 53 | import 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/caogen/eurekaclient/EurekaClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaclient; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @EnableDiscoveryClient 8 | @SpringBootApplication 9 | public class EurekaClientApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(EurekaClientApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/caogen/eurekaclient/controller/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaclient.controller; 2 | 3 | import com.caogen.eurekaclient.entity.User; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.cloud.client.ServiceInstance; 7 | import org.springframework.cloud.client.discovery.DiscoveryClient; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.Random; 12 | 13 | @RestController 14 | public class HelloController { 15 | 16 | private final Logger logger = LoggerFactory.getLogger(this.getClass()); 17 | 18 | @Resource 19 | private DiscoveryClient client; 20 | 21 | @RequestMapping("/hello") 22 | public String sayHello() { 23 | ServiceInstance instance = client.getLocalServiceInstance(); 24 | 25 | //让处理线程等待几秒,由于Hystrix默认超时时间为2000毫秒, 26 | // 所以这里采用0至3000的随机数让处理过程有一定概率发生超时来触发断路器 27 | try { 28 | int sleepTime = new Random().nextInt(3000); 29 | logger.info("sleepTime:" + sleepTime); 30 | Thread.sleep(sleepTime); 31 | }catch (Exception e) { 32 | logger.error("sayHello: " + e); 33 | e.printStackTrace(); 34 | } 35 | 36 | return "Hello,World! port:" + instance.getPort(); 37 | } 38 | 39 | @GetMapping(value = "/hello1") 40 | public String hello(@RequestParam String name) { 41 | return "Hello " + name; 42 | } 43 | 44 | @GetMapping(value = "/hello2") 45 | public User hello(@RequestHeader String name, @RequestHeader Integer age) { 46 | return new User(name, age); 47 | } 48 | 49 | @PostMapping(value = "/hello3") 50 | public String hello(@RequestBody User user) { 51 | return "Hello " + user.getName() + ", age " + user.getAge(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/caogen/eurekaclient/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaclient.entity; 2 | 3 | public class User { 4 | 5 | private String name; 6 | 7 | private Integer age; 8 | 9 | public User() { 10 | 11 | } 12 | 13 | public User(String name, Integer age) { 14 | this.name = name; 15 | this.age = age; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public Integer getAge() { 27 | return age; 28 | } 29 | 30 | public void setAge(Integer age) { 31 | this.age = age; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "User{" + 37 | "name='" + name + '\'' + 38 | ", age=" + age + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /eureka-client/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 随机端口设置 2 | server: 3 | port: 0 4 | 5 | # 关闭安全限制 6 | management: 7 | security: 8 | enabled: false 9 | 10 | # 服务应用名称 11 | spring: 12 | application: 13 | name: eureka-client 14 | 15 | # 注册中心地址 16 | eureka: 17 | client: 18 | serviceUrl: 19 | defaultZone: http://localhost:1111/eureka/ 20 | instance: 21 | instance-id: ${spring.application.name}:${random.int[10000,19999]} # 随机数配置实例ID 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/caogen/eurekaclient/EurekaClientApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaclient; 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 EurekaClientApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /eureka-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | eureka-server 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | eureka-server 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-eureka-server 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-dependencies 46 | ${spring-cloud.version} 47 | pom 48 | import 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-maven-plugin 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /eureka-server/src/main/java/com/caogen/eurekaserver/EurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaserver; 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 | @EnableEurekaServer //通过@EnableEurekaServer启动一个服务注册中心给其他应用使用 8 | @SpringBootApplication 9 | public class EurekaServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(EurekaServerApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /eureka-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 端口设置 2 | server: 3 | port: 1111 4 | 5 | # 关闭安全限制 6 | management: 7 | security: 8 | enabled: false 9 | 10 | # 注册中心配置 11 | eureka: 12 | server: 13 | enable-self-preservation: false # 关闭自我保护模式(缺省为打开) 14 | eviction-interval-timer-in-ms: 30000 # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms) 15 | instance: 16 | hostname: localhost 17 | client: 18 | register-with-eureka: false # 代表不向注册中心注册自己 19 | fetch-registry: false # 注册中心的职责就是维护服务实例,并不需要检索服务 20 | serviceUrl: 21 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 22 | -------------------------------------------------------------------------------- /eureka-server/src/test/java/com/caogen/eurekaserver/EurekaServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.eurekaserver; 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 EurekaServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /feign-consumer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | feign-consumer 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | feign-consumer 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-eureka 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-feign 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-actuator 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-dependencies 61 | ${spring-cloud.version} 62 | pom 63 | import 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /feign-consumer/src/main/java/com/caogen/feignconsumer/FeignConsumerApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 7 | 8 | @EnableFeignClients //开启Feign的支持功能 9 | @EnableDiscoveryClient //表明该应用是Eureka客户端 10 | @SpringBootApplication 11 | public class FeignConsumerApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(FeignConsumerApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /feign-consumer/src/main/java/com/caogen/feignconsumer/controller/ConsumerController.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer.controller; 2 | 3 | import com.caogen.feignconsumer.entity.User; 4 | import com.caogen.feignconsumer.service.ConsumerService; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @RestController 11 | public class ConsumerController { 12 | 13 | @Resource 14 | ConsumerService consumerService; 15 | 16 | @GetMapping(value = "/feign-consumer") 17 | public String helloConsumer() { 18 | return consumerService.hello(); 19 | } 20 | 21 | @GetMapping(value = "/feign-consumer2") 22 | public String helloConsumer2() { 23 | StringBuilder sb = new StringBuilder(); 24 | 25 | sb.append(consumerService.hello()).append("\n"); 26 | sb.append(consumerService.hello("caogen")).append("\n"); 27 | sb.append(consumerService.hello("caogen", 18)).append("\n"); 28 | sb.append(consumerService.hello(new User("caogen", 18))).append("\n"); 29 | 30 | return sb.toString(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /feign-consumer/src/main/java/com/caogen/feignconsumer/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer.entity; 2 | 3 | public class User { 4 | 5 | private String name; 6 | 7 | private Integer age; 8 | 9 | public User() { 10 | 11 | } 12 | 13 | public User(String name, Integer age) { 14 | this.name = name; 15 | this.age = age; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public Integer getAge() { 27 | return age; 28 | } 29 | 30 | public void setAge(Integer age) { 31 | this.age = age; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "User{" + 37 | "name='" + name + '\'' + 38 | ", age=" + age + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /feign-consumer/src/main/java/com/caogen/feignconsumer/service/ConsumerService.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer.service; 2 | 3 | import com.caogen.feignconsumer.entity.User; 4 | import org.springframework.cloud.netflix.feign.FeignClient; 5 | import org.springframework.web.bind.annotation.*; 6 | 7 | @FeignClient(name = "eureka-client", fallback = ConsumerServiceFallback.class) //通过@FeignClient注解指定服务名来绑定服务 8 | public interface ConsumerService { 9 | 10 | @RequestMapping(value = "/hello", method = {RequestMethod.GET}) //绑定REAT接口 11 | String hello(); 12 | 13 | @RequestMapping(value = "/hello1", method = {RequestMethod.GET}) 14 | String hello(@RequestParam("name") String name); 15 | 16 | @RequestMapping(value = "/hello2", method = {RequestMethod.GET}) 17 | User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age); 18 | 19 | @RequestMapping(value = "/hello3", method = {RequestMethod.POST}) 20 | String hello(@RequestBody User user); 21 | 22 | } -------------------------------------------------------------------------------- /feign-consumer/src/main/java/com/caogen/feignconsumer/service/ConsumerServiceFallback.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer.service; 2 | 3 | import com.caogen.feignconsumer.entity.User; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | public class ConsumerServiceFallback implements ConsumerService{ 8 | @Override 9 | public String hello() { 10 | return "error"; 11 | } 12 | 13 | @Override 14 | public String hello(String name) { 15 | return "error"; 16 | } 17 | 18 | @Override 19 | public User hello(String name, Integer age) { 20 | return new User("未知", 0); 21 | } 22 | 23 | @Override 24 | public String hello(User user) { 25 | return "error"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /feign-consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 端口设置 2 | server: 3 | port: 0 4 | 5 | # 应用名称设置 6 | spring: 7 | application: 8 | name: feign-consumer 9 | 10 | # 注册中心地址 11 | eureka: 12 | client: 13 | serviceUrl: 14 | defaultZone: http://localhost:1111/eureka/ 15 | instance: 16 | instance-id: ${spring.application.name}:${random.int[10000,19999]} # 随机数配置实例ID 17 | 18 | #开启hystrix(要不然降级失败) 19 | feign: 20 | hystrix: 21 | enabled: true -------------------------------------------------------------------------------- /feign-consumer/src/test/java/com/caogen/feignconsumer/FeignConsumerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.feignconsumer; 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 FeignConsumerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /hystrix-dashboard/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | hystrix-dashboard 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | hystrix-dashboard 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-hystrix 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-hystrix-dashboard 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-actuator 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-dependencies 56 | ${spring-cloud.version} 57 | pom 58 | import 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /hystrix-dashboard/src/main/java/com/caogen/hystrixdashboard/HystrixDashboardApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.hystrixdashboard; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 6 | 7 | @EnableHystrixDashboard //启用Hystrix仪表盘功能 8 | @SpringBootApplication 9 | public class HystrixDashboardApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(HystrixDashboardApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /hystrix-dashboard/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 -------------------------------------------------------------------------------- /hystrix-dashboard/src/test/java/com/caogen/hystrixdashboard/HystrixDashboardApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.hystrixdashboard; 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 HystrixDashboardApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.caogen 8 | springcloud 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | eureka-server 13 | eureka-client 14 | ribbon-consumer 15 | hystrix-dashboard 16 | turbine 17 | feign-consumer 18 | service-zuul 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ribbon-consumer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | ribbon-consumer 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | ribbon-consumer 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-eureka 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-ribbon 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-actuator 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-hystrix 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-test 57 | test 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.cloud 65 | spring-cloud-dependencies 66 | ${spring-cloud.version} 67 | pom 68 | import 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-maven-plugin 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /ribbon-consumer/src/main/java/com/caogen/ribbonconsumer/RibbonConsumerApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.ribbonconsumer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | @EnableCircuitBreaker //开启断路器功能 12 | @EnableDiscoveryClient //表明该应用是Eureka客户端 13 | @SpringBootApplication 14 | public class RibbonConsumerApplication { 15 | 16 | @Bean 17 | @LoadBalanced //注解开启客户端负载均衡 18 | RestTemplate restTemplate() { 19 | return new RestTemplate(); 20 | } 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(RibbonConsumerApplication.class, args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ribbon-consumer/src/main/java/com/caogen/ribbonconsumer/controller/ConsumerController.java: -------------------------------------------------------------------------------- 1 | package com.caogen.ribbonconsumer.controller; 2 | 3 | import com.caogen.ribbonconsumer.service.ConsumerService; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import javax.annotation.Resource; 8 | 9 | @RestController 10 | public class ConsumerController { 11 | 12 | @Resource 13 | ConsumerService consumerService; 14 | 15 | @GetMapping(value = "/ribbon") 16 | public String helloConsumer() { 17 | return consumerService.helloService(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ribbon-consumer/src/main/java/com/caogen/ribbonconsumer/service/ConsumerService.java: -------------------------------------------------------------------------------- 1 | package com.caogen.ribbonconsumer.service; 2 | 3 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.web.client.RestTemplate; 6 | 7 | import javax.annotation.Resource; 8 | 9 | @Service 10 | public class ConsumerService { 11 | 12 | @Resource 13 | RestTemplate restTemplate; 14 | 15 | @HystrixCommand(fallbackMethod = "helloFallback") 16 | public String helloService() { 17 | return restTemplate.getForObject("http://EUREKA-CLIENT/hello", String.class); 18 | } 19 | 20 | public String helloFallback() { 21 | return "error"; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ribbon-consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 端口设置 2 | server: 3 | port: 0 4 | 5 | # 应用名称设置 6 | spring: 7 | application: 8 | name: ribbon-consumer 9 | 10 | # 注册中心地址 11 | eureka: 12 | client: 13 | serviceUrl: 14 | defaultZone: http://localhost:1111/eureka/ 15 | instance: 16 | instance-id: ${spring.application.name}:${random.int[10000,19999]} # 随机数配置实例ID -------------------------------------------------------------------------------- /ribbon-consumer/src/test/java/com/caogen/ribbonconsumer/RibbonConsumerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.ribbonconsumer; 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 RibbonConsumerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /service-zuul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | service-zuul 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | service-zuul 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-zuul 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-eureka 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-dependencies 51 | ${spring-cloud.version} 52 | pom 53 | import 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /service-zuul/src/main/java/com/caogen/servicezuul/ServiceZuulApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.servicezuul; 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.zuul.EnableZuulProxy; 7 | 8 | @EnableZuulProxy //开启Zuul的API网关服务 9 | @EnableDiscoveryClient 10 | @SpringBootApplication 11 | public class ServiceZuulApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ServiceZuulApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /service-zuul/src/main/java/com/caogen/servicezuul/filter/AccessFilter.java: -------------------------------------------------------------------------------- 1 | package com.caogen.servicezuul.filter; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | @Component 12 | public class AccessFilter extends ZuulFilter { 13 | 14 | private final Logger logger = LoggerFactory.getLogger(this.getClass()); 15 | 16 | @Override 17 | public String filterType() { 18 | return "pre"; 19 | } 20 | 21 | @Override 22 | public int filterOrder() { 23 | return 0; 24 | } 25 | 26 | @Override 27 | public boolean shouldFilter() { 28 | return true; 29 | } 30 | 31 | @Override 32 | public Object run() { 33 | RequestContext ctx = RequestContext.getCurrentContext(); 34 | HttpServletRequest request = ctx.getRequest(); 35 | 36 | logger.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); 37 | 38 | Object accessToken = request.getParameter("token"); 39 | if(accessToken == null) { 40 | logger.warn("token is empty"); 41 | ctx.setSendZuulResponse(false); 42 | ctx.setResponseStatusCode(401); 43 | try { 44 | ctx.getResponse().getWriter().write("token is empty"); 45 | }catch (Exception e){} 46 | 47 | return null; 48 | } 49 | logger.info("ok"); 50 | 51 | return null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /service-zuul/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 5555 3 | spring: 4 | application: 5 | name: service-zuul 6 | 7 | # 关闭安全限制 8 | management: 9 | security: 10 | enabled: false 11 | 12 | # 路由配置 13 | zuul: 14 | routes: 15 | api-a: 16 | path: /api-a/** 17 | serviceId: eureka-client 18 | api-b: 19 | path: /api-b/** 20 | serviceId: feign-consumer 21 | 22 | # 注册中心地址 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://localhost:1111/eureka/ 27 | 28 | # 配置超时时间断路器才有效果(加入Zuul) 29 | ribbon: 30 | ReadTimeout: 30000 31 | ConnectTimeout: 30000 32 | -------------------------------------------------------------------------------- /service-zuul/src/test/java/com/caogen/servicezuul/ServiceZuulApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.servicezuul; 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 ServiceZuulApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /turbine/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.caogen 7 | turbine 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | turbine 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | Edgware.RELEASE 26 | 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-turbine 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-actuator 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-dependencies 51 | ${spring-cloud.version} 52 | pom 53 | import 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /turbine/src/main/java/com/caogen/turbine/TurbineApplication.java: -------------------------------------------------------------------------------- 1 | package com.caogen.turbine; 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.turbine.EnableTurbine; 7 | 8 | @EnableTurbine //开启Turbine 9 | @EnableDiscoveryClient 10 | @SpringBootApplication 11 | public class TurbineApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(TurbineApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /turbine/src/main/resources/application.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kcaogen/springcloud/86b14cc74bd274b7c08fe50e0d8a31e03e5519b2/turbine/src/main/resources/application.yml -------------------------------------------------------------------------------- /turbine/src/test/java/com/caogen/turbine/TurbineApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.caogen.turbine; 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 TurbineApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------