背景

为了防止服务消费链(多级服务之间的调用)上因某个服务出现故障,而导致级联故障,进而造成整个系统不可用(简称为:雪崩效应),推出了熔断、降级的处理方式:Hystrix断路器(类似生活中电路保险丝)来解决这些潜在问题。

熔断、降级的区别?

  • 熔断:

暂时切断对下游服务的调用,直接快速返回错误的响应信息,当检测到该下游服务节点调用响应正常后再恢复消费链路。

Spring Cloud Hystrix熔断保护 - 图1

关闭状态:服务正常放行。
打开状态:默认10秒内错误率达到50%,则打开,后续服务直接拒绝。
半开状态:打开后默认5秒后,半开状态,运行部分流量通过,如果没有改善,继续打开。

  • 降级

是指服务资源不够的时候,关闭部分不重要的资源,以维持重要服务正常运行的机制。

Hystrix隔离模式

Spring Cloud Hystrix熔断保护 - 图2

信号量模式

Spring Cloud Hystrix熔断保护 - 图3

特点:同步调用、开销小

线程池模式

Spring Cloud Hystrix熔断保护 - 图4

如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。
特点:支持超时、开销大、功能强。

参考:https://www.jianshu.com/p/e1a4d3bdf7c4

Spring 集成

引用

这里注意使用的版本,我使用的是springboot 2.1.5,springcloud Greenwich.SR2。

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  4. </dependency>

测试类

为了方便测试,我们设置熔断超时时间1秒。
如果5秒内,请求达到了4个,错误率达到50%以上,就开启跳闸,3秒以后再调用,会再执行一次业务方法

  1. /**
  2. * 启动类
  3. *
  4. * @author tianyunperfect
  5. * @date 2021/03/11
  6. */
  7. @SpringBootApplication
  8. @EnableHystrix
  9. @RestController
  10. public class ConsumerApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(ConsumerApplication.class);
  13. }
  14. /**
  15. * hystrix测试
  16. *
  17. * @return {@link String}* @throws InterruptedException 中断异常
  18. */
  19. @GetMapping("/test")
  20. @HystrixCommand(fallbackMethod = "fallBack",
  21. commandProperties = {
  22. //熔断超时时间1秒
  23. //如果5秒内,请求达到了4个,错误率达到50%以上,就开启跳闸,3秒以后再调用,会再执行一次业务方法
  24. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
  25. @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "5000"),
  26. @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "4"),
  27. @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
  28. @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000")
  29. })
  30. public String hystrixTest() throws InterruptedException {
  31. Thread.sleep(3000);
  32. return "Welcome Hystrix";
  33. }
  34. /**
  35. * 熔断保护
  36. * 注解在哪个方法上,返回值和方法参数一定要一致。
  37. *
  38. * @return {@link String}
  39. */
  40. private String fallBack() {
  41. return "请求失败,熔断保护";
  42. }
  43. }

线程池配置示例。

  1. @HystrixCommand(fallbackMethod = "error", commandProperties = {
  2. @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
  3. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "4000"),
  4. @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
  5. @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
  6. },
  7. threadPoolProperties = { // hystrix 中线程池配置
  8. @HystrixProperty(name = "coreSize", value = "1"),
  9. @HystrixProperty(name = "maxQueueSize", value = "10"),
  10. @HystrixProperty(name = "keepAliveTimeMinutes", value = "1000"),
  11. @HystrixProperty(name = "queueSizeRejectionThreshold", value = "8"),
  12. @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
  13. @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1500")
  14. })

测试结果

Python测试代码

  1. import datetime
  2. import requests
  3. for i in range(10000):
  4. start = datetime.datetime.now()
  5. requests.get("http://localhost:8881/test")
  6. end = datetime.datetime.now()
  7. print(str(datetime.datetime.now()) + ": " + str(end - start))

测试效果,

  • 5秒后开启熔断

image.png

  • 3秒后放行一个

image.png