Hystrix在Spring Cloud微服务体系中具备服务降级、接口熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能
本文基于Feign整合下的Hystrix使用,Spring Boot版本:2.1.14.RELEASE,SpringCloud 版本:Greenwich.SR5,依次说明Hystrix的一下功能:
- 服务降级
- 接口容断
- 线程和信号隔离
- 请求缓存
- 请求合并
- 服务监控
本文所用服务的交互说明:
Eureka Server:注册中心;服务B消费服务A,服务A部署两台实例,HystrixDashboard是服务监控的仪表板
(注:服务A、B均是标准的Spring Cloud服务)
1. 服务降级
1.在服务B的pom文件中引入Hystrix的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.在服务B的主类上添加注解@EnableCircuitBreaker启用断路器,如
@EnableCircuitBreaker
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceB {
public static void main(String[] args) {
SpringApplication.run(ServiceB.class, args);
}
}
3.实现服务B消费服务A的服务绑定接口,在实现类中给出各个接口的默认实现,如下:
服务A的服务绑定接口
@FeignClient(name = "SERVICE-A", fallback = HelloServiceFallback.class)
public interface HelloService {
/**
* hello
* @return
*/
@GetMapping("hello")
String hello();
}
服务A的服务绑定接口的实现类
@Component
public class HelloServiceFallback implements HelloService {
@Override
public String hello() {
return "SERVICE-A不在线";
}
}
4.服务B的配置文件加入
feign:
hystrix:
enabled: true #true 启用feign client 的hystrix 全局启用
5.验证
添加TestController类,在里面提供对服务A调用的接口,如:
@RestController
public class TestController {
@Autowired
private HelloService helloService;
@GetMapping("/getHello")
public String getHello() {
return helloService.hello();
}
}
启动注册中心和服务B,服务A不启动模拟其不在线,然后通过客户端访问,结果如下:
得到期望结果。服务降级有什么用呢?可以防止故障在服务间的蔓延,以优雅的方式处理异常,如果没有服务降级,那么就会报错:
com.netflix.client.ClientException: Load balancer does not have available server for client: SERVICE-A
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)
2. 接口容断
接口容断是指,调用指定的接口,在配置的时间内没有响应就会触发Hystrix的超时容断命令
1.在服务B的配置文件中添加如下配置:
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # 全局的接口超时容断时间(所有启用feign-hystrix的FeignClient接口超时时间都一样)
# hello: # 指定接口的超时容断时间(该名字为FeignClient中的接口名,若接口名字一样 配置将会一起生效)
# execution:
# isolation:
# thread:
# timeoutInMilliseconds: 3000 # Hystrix的超时容断时间 必须大于ribbon的处理超时时间 否则ribbon重试机制会失效 没有意义
注:Hystrix的超时容断时间 必须大于ribbon的处理超时时间(ReadTimeout) 否则ribbon重试机制会失效
2.在服务A中更新接口hello接口,模拟业务处理的耗时:
@GetMapping("hello")
public String hello() {
Random random = new Random();
long sleep = random.nextInt(30) * 1000L;
LOGGER.info("***********************sleep: {}", sleep);
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello" + name;
}
3.启动注册中心,服务A,服务B,通过客户端访问hello接口,得到如下响应:
- a.服务A控制台显示log:
2020-06-19 14:07:06.519 [http-nio-7712-exec-1] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 9000
2020-06-19 14:07:08.419 [http-nio-7712-exec-2] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 20000
2020-06-19 14:07:10.421 [http-nio-7712-exec-3] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 14000
2020-06-19 14:07:12.421 [http-nio-7712-exec-4] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 12000
2020-06-19 14:07:14.424 [http-nio-7712-exec-5] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 13000
2020-06-19 14:07:16.425 [http-nio-7712-exec-6] INFO c.goodcom.helloexec.HelloController - ***********************sleep: 27000
(注:ribbon配置每台实例重试1次,切换实例次数为2,此处只启动了一台服务A,所以对接口A的六次调用全部落在这一个实例上)
- b.服务B控制台响应:
2020-06-19 14:21:59.471 [http-nio-9900-exec-1] INFO c.g.f.controller.ConsumerController - cost time: 3185
响应时间为3185,大于配置的3000,所以对hello接口的掉用将会触发Hystrix的超时容断命令;但由于前面我们已经配置了对服务A的降级操作,所以此时客户端得到的响应仍为:
如果没有配置服务降级,将会直接包异常,如下
直接提示你:没有配置fallback
3.线程和信号隔离
后续添加,待续…
4.请求缓存
后续添加,待续…
5.请求合并
后续添加,待续…
6.服务监控
1.服务B的pom中引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.配置文件中开放相应的端点:hystrix.stream,以使HystrixDashboard应用可以对其进行监控;Spring Boot2.x默认只开放了health和info端,*号表示暴露所有端点,并且所有端点的base-path是actuator
management:
endpoints:
web:
exposure:
include: "*"
3.HystrixDashboard应用的pom引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
主类加入注解@EnableHystrixDashboard
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApplication.class, args);
}
}
同时配置文件加入配置:
management:
endpoints:
web:
exposure:
include: "*"
启动HystrixDashboard应用,并访问http://localhost:20088/hystrix(端口自己指定),如下
然后点击【Monitor按钮】,即可得到对应服务的监控仪表盘
结束