断路器 Hystrix
1.分布式系统面临的问题?
多个微服务之间的调用的链路上某个微服务的调用时间过长或者不可用,对微服务的调用就会占用越来越多的系统资源,进而引起系统崩溃,即"雪崩效应"
2.Hystrix是什么?
是一个用于处理分布式系统的延迟和容错的开源库,能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。"断路器"本身是一种开关装置,当某个服务单元发生故障后,通过断路器的故障监控(类似保险丝),向调用方返回预期的可处理的备选响应(FallBack),而不是长时间等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间的占用,从而避免故障在分布式系统中的蔓延,乃至雪崩。
3.Hystrix能干嘛?
服务降级(fallback)
服务熔断(break)
服务限流(flowlimit)
接近实时的监控
4.Hystrix重要概念?
服务降级:服务器忙,请稍后再试,不让客户端等待并且立刻返回一个友好的提示
服务熔断:类似保险丝,达到最大服务访问量后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
服务限流:秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒N个,有序进行
5.哪些情况会发生服务降级?
程序出现异常
超时
服务熔断触发服务降级
线程池/信号量打满也会导致服务降级
6.Hystrix的超时的坑?
配置的超时时间应该大于Ribbon的超时时间,hystrix的默认超时时间是1000ms
hystrix: command: default: execution: timeout: #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据 enable: true isolation: thread: ## 配置hystrix的超时时间 timeoutInMilliseconds: 5000
7.Hystrix的使用
1.pom引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2.修改yml配置文件
## 开启feign中的hystrix feign: hystrix: enabled: true httpclient: connection-timeout: 5000 hystrix: command: default: execution: timeout: #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据 enable: true isolation: thread: ## 配置hystrix的超时时间 timeoutInMilliseconds: 5000
3.主启动类添加 @EnableHystrix 注解
@SpringBootApplication @EnableFeignClients @EnableHystrix public class OrderHystrixMain80 { public static void main(String[] args) { SpringApplication.run(OrderHystrixMain80.class, args); } }
4.服务降级与熔断的配置
4.1指定在调用服务超时后发生降级执行 getPaymentTimeOutHandler() 方法
@GetMapping("/consumer/payment/timeout/get/{id}") @HystrixCommand(fallbackMethod = "getPaymentTimeOutHandler", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) public String getPaymentTimeOut(@PathVariable Long id) { return paymentHystrixService.paymentInfo_Timeout(id); } public String getPaymentTimeOutHandler(Long id) { return "我是消费者80,对方系统繁忙或者自己运行出错,o(╥﹏╥)o ~"; }
4.2服务熔断的配置
// 服务熔断demo @GetMapping("/consumer/payment/circuitBreaker/get/{id}") @HystrixCommand(fallbackMethod = "paymentCircuitBreakerHandler", commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 是否开启断路器 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 请求次数 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间窗口期 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") // 失败率达到多少后跳闸 }) public String paymentCircuitBreaker(@PathVariable Long id) { if (id < 0) { throw new RuntimeException("****id*****不能为负数"); } String serialNumber = IdUtil.simpleUUID(); return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber; } public String paymentCircuitBreakerHandler(Long id) { return "id不能为负数,请稍后再试,o(╥﹏╥)o~~~ id:" + id; }
4.3Hystrix全局服务降级(类上使用@DefaultProperties,方法上使用@HystrixCommand)
@DefaultProperties(defaultFallback = "global_hystrix_fallback")
@HystrixCommand
4.4Hystrix通配服务降级FeignFallback
1.实现Feign接口,所实现的方法就是降级处理方法
2.在Feign接口@FeignClient注解上指定实现类即指定降级处理
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentHystrixServiceImpl.class) public interface PaymentHystrixService { @GetMapping("/payment/hystrix/ok/{id}") public String paymentInfo_OK(@PathVariable("id") Long id); @GetMapping("/payment/hystrix/timeout/{id}") public String paymentInfo_Timeout(@PathVariable("id") Long id); }
@Component public class PaymentHystrixServiceImpl implements PaymentHystrixService { @Override public String paymentInfo_OK(Long id) { return "降级方法"; } @Override public String paymentInfo_Timeout(Long id) { return "降级方法"; } }
8.Hystrix图形化Dashboard搭建
1.pom引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
2.yml配置端口即可
3.主启动类添加 @EnableHystrixDashboard 注解
@SpringBootApplication @EnableHystrixDashboard public class HystrixDashboardMain9001 { public static void main(String[] args) { SpringApplication.run(HystrixDashboardMain9001.class, args); } }
4.需要监控的类添加下方依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
5.监控的服务主启动类上添加 @EnableCircuitBreaker 注解
@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; }
注意:由于版本原因,默认的监控流地址不是/hystrix.stream需要在监控的服务方添加配置
6.访问地址 http://localhost:9001/hystrix