Hystrix 实现服务熔断与降级
本文为博主原创,未经允许不得转载:
目录:
1. 服务雪崩,服务熔断,服务降级概念
2. Hystrix 概念
3. Hystrix 使用及默认配置
4. @HystrixCommond 注解使用
5. 常用熔断器配置
1. 服务雪崩,服务熔断,服务降级:
服务雪崩:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应。如 A 服务调用 B 服务,B服务再调用C服务,
当C服务不可用,且大量请求从 A端请求到C端时,因为C 服务不可用,会导致线程池里所有线程都因等待响应而被阻塞, 从而造成服务雪崩
服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,
快速释放资源。如果目标服务情况好转则恢复调用。需要说明的是熔断其实是一个框架级的处理,那么这套熔断机制的设计,基本上业内用
的是断路器模式
,与熔断器是相同的原理。
服务降级:就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。
使用场景:
1. 当系统服务遇到双十一,大促销等场景时,可对不重要的服务进行降级,释放出服务器的资源,优先保障核心业务
2. 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!
服务熔断也是服务降级的一种保护措施,还包括:限流降级,开关降级
2. Hystrix 基本概念:
Hystrix并不是Spring的,而是NetFlix公司开源的,提供超时机制,限流,熔断,降级最全面的实现.
原理:通过“命令模式”的方式,继承(HystrixCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback)
3. Hystrix 使用及默认配置
3.1 添加 pom 依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
<!--hystrix官网-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.18</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
3.2 默认配置及常用配置:
3.2.1 线程隔离配置:
hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread|Semaphore
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时间,默认1000ms
hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断,默认true
3.2.2 信号量隔离配置
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests 最大并发请求数,默认10,该参数当使用
ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和
选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。
3.2.3 ThreadPool 相关参数
hystrix.threadpool.default.coreSize 并发执行的最大线程数,默认10
4. @HystrixCommand 的使用
4.1 在需要熔断与降级的方法上使用 @HystrixCommand 注解
@HystrixCommand(fallbackMethod = "onError", ignoreExceptions = ClassNotFoundException.class, commandProperties = { @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"), @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")}, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "5"), @HystrixProperty(name = "maximumSize", value = "5"), @HystrixProperty(name = "maxQueueSize", value = "10") }) @RequestMapping("/sayHello") public String sayHello(String name) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello, " + name; } /** * 如果fallback方法的参数和原方法参数个数不一致,则会出现FallbackDefinitionException: fallback method wasn't found */ public String onError(String name) { return "Error!!!" + name; }
4.2 添加 HystrixCommand 注解使用的切面配置
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.Servlet; @Configuration public class HystrixConfig { /** * A {@link ServletContextInitializer} to register {@link Servlet}s in a Servlet 3.0+ container. */ @Bean public ServletRegistrationBean hystrixMetricsStreamServlet() { return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream"); } /** * AspectJ aspect to process methods which annotated with {@link HystrixCommand} annotation. * * {@link HystrixCommand} annotation used to specify some methods which should be processes as hystrix commands. */ @Bean public HystrixCommandAspect hystrixCommandAspect() { return new HystrixCommandAspect(); } }
5. 常用熔断器配置
1、circuitBreaker.enabled
是否启用熔断器,默认是TURE。
2、circuitBreaker.forceOpen
熔断器强制打开,始终保持打开状态。默认值FLASE。
3、circuitBreaker.forceClosed
熔断器强制关闭,始终保持关闭状态。默认值FLASE。
4、circuitBreaker.errorThresholdPercentage
设定错误百分比,默认值50%,例如一段时间(10s)内有100个请求,其中有55个超时或者异常返回了,那么这段时间内的错误百分比是55%,大于了默认值50%,这种情况下触发熔断器-打开。
5、circuitBreaker.requestVolumeThreshold
默认值20.意思是至少有20个请求才进行errorThresholdPercentage错误百分比计算。比如一段时间(10s)内有19个请求全部失败了。错误百分比是100%,但熔断器不会打开,因为requestVolumeThreshold的值是20. 这个参数非常重要,熔断器是否打开首先要满足这个条件
半开试探休眠时间,默认值5000ms。当熔断器开启一段时间之后比如5000ms,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。