Hystrix集群及监控turbine
前面Dashboard演示的仅仅是单机服务监控,实际项目基本都是集群,所以这里集群监控用的是turbine。
turbine是基于Dashboard的。
先搞个集群;
再microservice-student-provider-hystrix-1004项目的基础上再搞一个microservice-student-provider-hystrix-1005
代码和配置都复制一份,然后修改几个地方;
1、yml配置
1 --- 2 server: 3 port: 1004 4 context-path: / 5 spring: 6 datasource: 7 type: com.alibaba.druid.pool.DruidDataSource 8 driver-class-name: com.mysql.jdbc.Driver 9 url: jdbc:mysql://localhost:3306/xufanqi?useUnicode=true&characterEncoding=utf8 10 username: root 11 password: 123 12 jpa: 13 hibernate: 14 ddl-auto: update 15 show-sql: true 16 application: 17 name: microservice-student 18 profiles: provider-hystrix-1004 19 20 eureka: 21 instance: 22 hostname: localhost 23 appname: microservice-student 24 instance-id: microservice-student:1004 25 prefer-ip-address: true 26 client: 27 service-url: 28 defaultZone: http://eureka2001.javaqi.com:2001/eureka/,http://eureka2002.javaqi.com:2002/eureka/,http://eureka2003.javaqi.com:2003/eureka/ 29 30 info: 31 groupId: com.javaxl.testSpringcloud 32 artifactId: microservice-student-provider-hystrix-1004 33 version: 1.0-SNAPSHOT 34 userName: http://javaqi.com 35 phone: 123456 36 37 hystrix: 38 command: 39 default: 40 execution: 41 isolation: 42 thread: 43 timeoutInMilliseconds: 1500 44 45 --- 46 server: 47 port: 1005 48 context-path: / 49 spring: 50 datasource: 51 type: com.alibaba.druid.pool.DruidDataSource 52 driver-class-name: com.mysql.jdbc.Driver 53 url: jdbc:mysql://localhost:3306/xufanqi?useUnicode=true&characterEncoding=utf8 54 username: root 55 password: 123 56 jpa: 57 hibernate: 58 ddl-auto: update 59 show-sql: true 60 application: 61 name: microservice-student 62 profiles: provider-hystrix-1005 63 64 eureka: 65 instance: 66 hostname: localhost 67 appname: microservice-student 68 instance-id: microservice-student:1005 69 prefer-ip-address: true 70 client: 71 service-url: 72 defaultZone: http://eureka2001.javaqi.com:2001/eureka/,http://eureka2002.javaqi.com:2002/eureka/,http://eureka2003.javaqi.com:2003/eureka/ 73 74 info: 75 groupId: com.javaxl.testSpringcloud 76 artifactId: microservice-student-provider-hystrix-1005 77 version: 1.0-SNAPSHOT 78 userName: http://javaqi.com 79 phone: 123456 80 81 hystrix: 82 command: 83 default: 84 execution: 85 isolation: 86 thread: 87 timeoutInMilliseconds: 1500 88 89 --- 90 server: 91 port: 1006 92 context-path: / 93 spring: 94 datasource: 95 type: com.alibaba.druid.pool.DruidDataSource 96 driver-class-name: com.mysql.jdbc.Driver 97 url: jdbc:mysql://localhost:3306/xufanqi?useUnicode=true&characterEncoding=utf8 98 username: root 99 password: 123 100 jpa: 101 hibernate: 102 ddl-auto: update 103 show-sql: true 104 application: 105 name: microservice-student 106 profiles: provider-hystrix-1006 107 108 eureka: 109 instance: 110 hostname: localhost 111 appname: microservice-student 112 instance-id: microservice-student:1006 113 prefer-ip-address: true 114 client: 115 service-url: 116 defaultZone: http://eureka2001.javaqi.com:2001/eureka/,http://eureka2002.javaqi.com:2002/eureka/,http://eureka2003.javaqi.com:2003/eureka/ 117 118 info: 119 groupId: com.javaxl.testSpringcloud 120 artifactId: microservice-student-provider-hystrix-1006 121 version: 1.0-SNAPSHOT 122 userName: http://javaqi.com 123 phone: 123456 124 125 hystrix: 126 command: 127 default: 128 execution: 129 isolation: 130 thread: 131 timeoutInMilliseconds: 1500
2、启动类配置
1 package com.javaqi.microservicestudentproviderhystrix; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.autoconfigure.domain.EntityScan; 6 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 7 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8 9 @EnableCircuitBreaker 10 @EntityScan("com.javaqi.*.*") 11 @EnableEurekaClient 12 @SpringBootApplication 13 public class MicroserviceStudentProviderHystrixApplication { 14 15 public static void main(String[] args) { 16 SpringApplication.run(MicroserviceStudentProviderHystrixApplication.class, args); 17 } 18 19 }
这样的话 就有了 hystrix集群服务;
3、我们新建项目microservice-student-consumer-hystrix-turbine-91
pom.xml加下依赖
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-actuator</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>org.springframework.cloud</groupId> 7 <artifactId>spring-cloud-starter-turbine</artifactId> 8 </dependency>
4、application.yml
1 server: 2 port: 91 3 context-path: / 4 eureka: 5 client: 6 service-url: 7 defaultZone: http://eureka2001.javaqi.com:2001/eureka/,http://eureka2002.javaqi.com:2002/eureka/,http://eureka2003.javaqi.com:2003/eureka/ 8 turbine: 9 app-config: microservice-student # u6307u5B9Au8981u76D1u63A7u7684u5E94u7528u540Du79F0 10 clusterNameExpression: "'default'" #u8868u793Au96C6u7FA4u7684u540Du5B57u4E3Adefault 11 spring: 12 application: 13 name: turbine
1、新建启动类MicroserviceStudentConsumerHystrixTurbine91Application 加注解:@EnableTurbine
1 package com.javaqi.microservicestudentconsumerhystrixturbine91; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 7 import org.springframework.cloud.netflix.turbine.EnableTurbine; 8 9 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) 10 @EnableTurbine 11 public class MicroserviceStudentConsumerHystrixTurbine91Application { 12 13 public static void main(String[] args) { 14 SpringApplication.run(MicroserviceStudentConsumerHystrixTurbine91Application.class, args); 15 } 16 17 }
测试:
先启动三个eureka,然后把1004 1005 带hystrix的服务都启动;
microservice-student-consumer-80这个也启动,方便测试;
dashboard,turbine启动;
这样的话 http://localhost/student/hystrix 就能调用服务集群;
http://localhost:91/turbine.stream 可以监控数据,实时ping 返回data
Feign、Hystrix整合
前面的代码,用@HystrixCommand fallbackMethod是很不好的,因为和业务代码耦合度太高,不利于维护,所以需要解耦,这我们讲下Feign Hystrix整合。
1、microservice-student-provider-hystrix项目修改
我们不用原先那套。按照正常的逻辑来写;
StudentService加新的接口方法:
1 /** 2 * 测试Hystrix服务降级 3 * @return 4 */ 5 public Map<String,Object> hystrix(); 6 7 StudentServiceImpl写具体实现: 8 @Override 9 public Map<String, Object> hystrix() { 10 Map<String,Object> map=new HashMap<String,Object>(); 11 map.put("code", 200); 12 map.put("info","工号【"+port+"】正在为您服务"); 13 return map; 14 }
StudentProviderController正常调用service方法:
1 /** 2 * 测试Hystrix服务降级 3 * @return 4 * @throws InterruptedException 5 */ 6 @ResponseBody 7 @GetMapping(value="/hystrix") 8 // @HystrixCommand(fallbackMethod="hystrixFallback") 9 public Map<String,Object> hystrix() throws InterruptedException{ 10 Thread.sleep(100); 11 // Map<String,Object> map=new HashMap<String,Object>(); 12 // map.put("code", 200); 13 // map.put("info","工号【"+port+"】正在为您服务"); 14 return this.studentService.hystrix(); 15 } 16 17 // public Map<String,Object> hystrixFallback() throws InterruptedException{ 18 // Map<String,Object> map=new HashMap<String,Object>(); 19 // map.put("code", 500); 20 // map.put("info", "系统【"+port+"】繁忙,稍后重试"); 21 // return map; 22 // }
2、microservice-common项目新建FallbackFactory类,解耦服务熔断服务降级
StudentClientService接口,新增getInfo方法;
1 /** 2 * 服务熔断降级 3 * @return 4 */ 5 @GetMapping(value="/student/hystrix") 6 public Map<String,Object> hystrix();
新建 StudentClientFallbackFactory 类,实现FallbackFactory<StudentClientService>接口;
1 package com.javaqi.microservicecommon.service; 2 3 import com.javaqi.microservicecommon.entity.Student; 4 import feign.hystrix.FallbackFactory; 5 import org.springframework.stereotype.Component; 6 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 @Component 12 public class StudentClientFallbackFactory implements FallbackFactory<StudentClientService> { 13 14 @Override 15 public StudentClientService create(Throwable cause) { 16 return new StudentClientService() { 17 18 @Override 19 public boolean save(Student student) { 20 return false; 21 } 22 23 @Override 24 public List<Student> list() { 25 return null; 26 } 27 28 @Override 29 public Map<String, Object> hystrix() { 30 Map<String,Object> map=new HashMap<String,Object>(); 31 map.put("code", 500); 32 map.put("info", "系统繁忙,稍后重试"); 33 return map; 34 } 35 36 @Override 37 public Student get(Integer id) { 38 return null; 39 } 40 41 @Override 42 public boolean delete(Integer id) { 43 return false; 44 } 45 46 @Override 47 public String ribbon() { 48 return null; 49 } 50 }; 51 } 52 53 }
StudentClientService接口的@FeignClient注解加下 fallbackFactory属性
1 @FeignClient(value="MICROSERVICE-STUDENT",fallbackFactory=StudentClientFallbackFactory.class)
这类我们实现了 降级处理方法实现;
3、microservice-student-consumer-feign-80修改 支持Hystrix
StudentConsumerFeignController新增方法调用
1 /** 2 * Feign整合Hystrix服务熔断降级 3 * @return 4 * @throws InterruptedException 5 */ 6 @GetMapping(value="/hystrix") 7 public Map<String,Object> hystrix() throws InterruptedException{ 8 return studentClientService.hystrix(); 9 }
4、microservice-student-consumer-feign-80的application.yml加上hystrix支持
1 feign: 2 hystrix: 3 enabled: true
1、microservice-student-consumer-feign-80的启动类上添加公共模块
@ComponentScan(basePackages = {"com.javaxl.microservicecommon","com.javaxl.microservicestudentconsumerfeign80"})
注意:
1.公共子项目与当前子项目的基包都要扫描到;
2.只指定公共子模块为基包会导致本子项目的springmvc功能失效;
3.只指定本子项目为基包会导致feign与Hystrix集成失败,从而导致服务熔断功能失效
1 package com.javaqi.microservicestudentconsumerfeign80; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 7 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8 import org.springframework.cloud.netflix.feign.EnableFeignClients; 9 import org.springframework.context.annotation.ComponentScan; 10 11 @ComponentScan(basePackages = {"com.hmc.microservicecommon","com.hmc.microservicestudentconsumerfeign80"})//扫描公共模块 12 @EnableFeignClients(value = "com.hmc.*.*") 13 @EnableEurekaClient 14 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) 15 public class MicroserviceStudentConsumerFeign80Application { 16 17 public static void main(String[] args) { 18 SpringApplication.run(MicroserviceStudentConsumerFeign80Application.class, args); 19 } 20 21 }
测试开启三个eureka,以及带hystrix的provider,和带feign,hystrix的consummer。
测试的话,也是没问题的。0.9秒的话,返回正常信息;超过1秒的话,就返回错误提示
集群后超时设置
上面错误是什么原因呢,咱们明明在Hystrix中的application.yml中设置了
1 hystrix: 2 command: 3 default: 4 execution: 5 isolation: 6 thread: 7 timeoutInMilliseconds: 1500
这里因为还有一个 feign 也有一个超时时间的设置,当然feign底层是 ribbon的封装,所以 直接配置ribbon,ribbon默认超时也是1秒。
所以这里都是强制要求,ribbon的超时时间要大于hystrix的超时时间,否则 hystrix自定义的超时时间毫无意义。
所以还得microservice-student-consumer-feign-80上加个 ribbon超时时间设置
1 ribbon: 2 ReadTimeout: 10000 3 ConnectTimeout: 9000