熔断机制
熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
当检测该节点微服务调用响应正常后,恢复调用链路。
在SpringCloud框架里,熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阀值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand
参考大神写的文章:https://martinfowler.com/bliki/CircuitBreaker.html
熔断机制主要通过断路器来实现
断路器原理
断路器状态:
- Closed:熔断器关闭状态(所有请求返回成功)
- Open:熔断器打开状态(调用次数累计到达阈值或者比例,熔断器打开,服务直接返回错误)
- Half Open:熔断器半开状态(默认时间过后,进入半熔断状态,允许定量服务请求,如果调用都成功,则认为恢复了,则关闭断路器,反之打开断路器)
断路器的基本原理非常简单。将受保护的函数调用包装在断路器对象中,该对象将监视故障。一旦故障达到一定阈值,断路器将跳闸,并且所有进一步的断路器调用都会返回错误,而根本不会进行受保护的调用。这个简单的断路器避免了在电路断开时发出受保护的呼叫,但是当情况恢复正常时,将需要外部干预才能将其重置。对于建筑物中的电路断路器,这是一种合理的方法,但是对于软件断路器,可以让断路器本身检测基础调用是否再次正常工作。可以通过在适当的时间间隔后再次尝试受保护的调用来实现这种自我重置行为,并在成功后重置断路器。
服务熔断案例
继续使用前一章(【SpringCloud】Hystrix服务降级(十))的项目
1、在服务提供者模块(test-springcloud-provider-payment8008)中,编辑业务类PaymentService,新增一下内容:
1 // 服务熔断 2 @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", 3 // 属性设置参考:HystrixCommandProperties 4 commandProperties = { 5 // 是否开启断路器,默认true 6 @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), 7 // 请求次数,默认20 8 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), 9 // 时间窗口期,默认5000 10 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), 11 // 失败率到达多少后跳闸,默认50 12 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") 13 }) 14 public String paymentCircuitBreaker(@PathVariable("id") Integer id){ 15 if(id < 0) { 16 throw new RuntimeException("======== id 不能为负数 ========="); 17 } 18 String serialNumber = UUID.randomUUID().toString(); 19 return Thread.currentThread().getName() + " " + "调用成功,流水号:" + serialNumber; 20 } 21 22 public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){ 23 return " id 不能为负数,请稍后再试, id == " + id; 24 }
2、在controller中(PaymentController),新增以下方法:
1 @GetMapping(value = "/payment/hystrix/circuit/{id}") 2 public String paymentInfo_circuit(@PathVariable("id") Integer id) { 3 String result = paymentService.paymentCircuitBreaker(id); 4 log.info("result===" + result); 5 return result; 6 }
3、测试
1)启动项目(test-springcloud-provider-payment8008)
2)访问地址:http://localhost:8008/payment/hystrix/circuit/1,正常访问
3)访问地址:http://localhost:8008/payment/hystrix/circuit/-1,连续访问改地址,
页面显示,服务降级,错误信息,继续使之错误次数达到10次以上,
然后访问地址:http://localhost:8008/payment/hystrix/circuit/1,可以看到服务还是不可用,
过一段时间,继续访问,发现服务可以