hystrix是Netlifx开源的一款容错框架,防雪崩利器,具备服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能。
Hystrix使用场景
1.调用超时时间比你自己定义的阈值要长。
2.线程池满了,应该立即拒绝请求,而不是排队。
3.在一段时间内,如果服务的错误百分比超过了一个阈值,就会触发一个断路器来停止对特定服务的所有请求,无论是手动还是自动的。
1.服务降级
使用场景:
比如双十一买东西出现,哎哟喂,被挤爆了。app秒杀某个商品提示网络开小差,请稍后再试。
使用方法:
(1)添加pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
(2)启动类加@EnableCircuitBreaker注解
(3)使用RestTemplate请求数据 加上@HystrixCommand(fallbackMethod=“fallback”)
(4)fallback是方法 在方法中保持传参和返回值相同。
(5)对(3)(4)的举例,抛出异常或者请求时间过长,则走fallback2
@GetMapping("/user/test")
@HystrixCommand(fallbackMethod = "fallback2")
public String test(@RequestParam ("number")Integer number) {
if (number == 1) {
return "success";
}
RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject("http://127.0.0.1:8081/rw/user/test", String.class);
return str;
}
private String fallback2(Integer number) {
return "太拥挤了,请稍后再试2";
}
(6)修改超时时间
通过application.yum配置文件进行修改:
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #请求命令执行超时时间
2.依赖隔离:
(1)为每一个hystrixCommand提供一个线程池,自动实现了依赖隔离,即使线程池满了也不会影响其他进程。
线程池隔离:是Hystrix最基本的资源隔离技术。Hystrix会将每一次服务调用请求,封装在一个Command对象内,每个Command都是使用线程池内的一个线程去执行的,这样就能跟调用线程本身隔离开来,避免因为外部依赖的接口调用超时,导致调用线程本身被卡死的情况。
信号量隔离:每接收一个请求,都是服务自身线程去直接调用依赖服务 ,信号量就相当于一道关卡,每个线程通过关卡后,信号量数量减1,当为0时不再允许线程通过,而是直接执行fallback逻辑并返回,说白了仅仅做了一个限流。
3.服务熔断:
(1)服务在高并发的情况下出现进程阻塞,导致当前线程不可用,慢慢的全部线程阻塞 ,导致服务器雪崩。这时直接熔断整个服务,而不是一直等到服务器超时。
(2)断路器全开时:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象 断路器完全打开 那么下次请求就不会请求到该服务
半开:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时 断路器关闭
关闭:当服务一直处于正常状态 能正常调用
@HystrixCommand(fallbackMethod = "fallback2", commandProperties = {
/* @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"),*/
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
})
@GetMapping("/user/test")
public String test(@RequestParam ("number")Integer number) {
if (number == 1) {
return "success";
}
RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject("http://127.0.0.1:8081/rw/user/test", String.class);
return str;
}
circuitBreaker.enabled :true 打开熔断 默认开启
circuitBreaker.requestVolumeThreshold: 当在配置时间窗口内达到此数量的失败后,进行短路。默认20个
circuitBreaker.sleepWindowInMilliseconds:短路多久以后开始尝试是否恢复,默认5s
circuitBreaker.errorThresholdPercentage:出错百分比阈值,当达到此阈值后,开始短路。默认50%
4.服务熔断监控
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream"); //配置监控地址
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
#actuator监控
management:
endpoints:
web:
exposure:
include: health, info,hystrix.stream
测试类
@RestController
public class ClientController {
// http://localhost:9200/demo
@HystrixCommand(fallbackMethod = "fail2")
@RequestMapping("/demo")
public String demo() {
return "ok";
}
// http://localhost:9200/demo2
@HystrixCommand(fallbackMethod = "fail2")
@RequestMapping("/demo2")
public String demo2() {
throw new RuntimeException();
}
private String fail2() {
System.out.println("fail2");
throw new RuntimeException();
}
}
2.启动类添加注解 @EnableHystrixDashboard //断路器可视化
访问Hystrix仪表盘地址 :http://localhost:9200/hystrix
http://localhost:9200/hystrix.stream访问
点击Monitor Stream进入,
刚开始这个界面是空的,浏览器输入测试地址 http://localhost:9200/demo 多少刷新几次
当我们刷新这个监控页面 http://localhost:9200/hystrix/monitor?stream=http%3A%2F%2Flocalhost%3A9200%2Fhystrix.stream
会报错如下:
Proxy opening connection to: http://localhost:9200/hystrix.stream
2024-06-15 17:34:06.461 ERROR 68336 --- [ XNIO-1 task-19] ashboardConfiguration$ProxyStreamServlet : Error proxying request: http://localhost:9200/hystrix.stream
java.lang.RuntimeException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
at org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardConfiguration$ProxyStreamServlet.doGet(HystrixDashboardConfiguration.java:215) ~[spring-cloud-netflix-hystrix-dashboard-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:645) [javax.servlet-api-4.0.1.jar:4.0.1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) [javax.servlet-api-4.0.1.jar:4.0.1]
当我们刷新监控页面报错 java.io.IOException: 你的主机中的软件中止了一个已建立的连接。这个报错是正常的,因为进入这个监控页面后,前后端建立了连接,我们刷新页面,强制中断了这个连接,所以报错 你的主机中的软件中止了一个已建立的连接。
参考:
https://zhuanlan.zhihu.com/p/591597024