Hystrix作为一个容错组件,本文从它的作用、熔断设计、工作流程和应用方面一一道来,帮助大家了解如何使用。
要讲Hystrix,我们就要讲一种场景,在微服务架构中,如果底层服务出现故障,服务无法响应或者响应延迟,其调用者等待时间会变长,整个系统的性能就会下降,此时如果有大量的请求涌入,容器的资源就会被消耗掉,从而导致所有服务瘫痪,这就是灾难性雪崩效应,本文主要讲使用Hystrix进行服务熔断来解决雪崩问题。
Hystrix 是由 Netflix 开源的一个延迟和容错库,用于隔离访问远程系统、服务和第三方库,防止级联失败,从而提升系统的可用性与容错性。
(1)降级
当服务负载过高,或出现故障、程序运行异常、超时、服务熔断触发服务降级、线程池/信号量打满等情况时,可以对服务进行降级,返回指定的托底数据,提高用户体验。
(2)熔断
当请求失败率达到指定阈值,服务会自动进行降级,在指定的时间内调用方就不会访问提供方,直接返回兜底数据,从而避免程序不断的尝试可能失败的操作浪费资源。Hystrix提供快速失败和快速恢复的支持。
(3)隔离
隔离分为线程池隔离和信号量隔离。线程池隔离把请求分配给不同的资源的线程池,让线程池创建线程去调用服务执行任务,具体的线程数由线程池做限制,而使用信号量,真实的工作线程就是由我们自己创建的,执行任务时通过信号量做一个数量的限制。
(4)限流
限流机制主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。
(5)运维监控
Hystrix 可以近乎实时地监控运行指标和配置的变化,以便快速发现问题。
(1)熔断请求判断机制算法:使用无锁循环队列计数,每个熔断器默认维护10个bucket,每1秒一个bucket,每个blucket记录请求的成功、失败、超时、拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。
(2)熔断恢复:对于被熔断的请求,每隔5s允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。
(3)熔断报警:对于熔断的请求打日志,异常请求超过某些设定则报警。
当调用出现错误时,开启一个时间窗(默认 10秒),统计调用次数是否达到最小请求数
流程图如下:
6.1 服务消费者
(1)添加pom依赖
org.springframework.cloud spring-cloud-starter-netflix-hystrix
(2)启动类上加@EnableHystrix注解
@EnableHystrix @SpringBootApplication public class TestConsumerApplication { public static void main(String[] args) { SpringApplication.run(TestConsumerApplication.class, args); } }
(3)添加@HystrixCommand
@RestController public class HelloController { @Reference(version="1.0.0") private HelloService helloService; @RequestMapping("/hello") @HystrixCommand(fallbackMethod = "helloFallback", commandProperties = { @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "3000"), @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "5"), @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "6"), @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "45") }) public String hello() { return helloService.getHello(); } public String helloFallback() { return "fallback,hello"; } }
注:fallbackMethod方法对应的入参和返回值和原方法一致。
(4) 注解@HystrixProperty的name取值
6.2 服务提供者
(1)添加pom依赖
org.springframework.cloud spring-cloud-starter-netflix-hystrix
(2)启动类上加@EnableHystrix注解
@EnableHystrix @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
(3)方法上加@HystrixCommand
@Service(version = "1.0.0", interfaceClass = HelloService.class) public class HelloServiceImpl implements HelloService{ @HystrixCommand @Override public String getHello() { return "provider, hello"; } }