一、Hystrix是什么
-
在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也是很常见的。
-
Hystrix 可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制。
-
Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务出现故障时在整个系统所有的依赖服务调用中进行蔓延;
-
Hystrix 还提供故障时的 fallback 降级机制。 总而言之,Hystrix 通过这些方法帮助我们提升分布式系统的可用性和稳定性。
二、为什么要使用Hystrix
-
为第三方系统访问(通常是指通过网络) 中发送的延时和错误(例如:服务数据库异常)提供保护和控制.
-
终止复杂分布式系统中的级联故障 .
-
快速失败(熔断)和快速恢复.
-
回退(fallback) 并且在可能的情况下进行服务降级.
-
启用近乎实时的监视,警报和操作控制.
三、Hystrix解决了什么问题
在复杂的分布式体系服务中,应用可能拥有数十种依赖程序,每种依赖程序都不可避免的会出现某个时刻的失败。如果主机应用程序未能与这些外部故障进行故障隔离,那么可能导致整个应用服务被宕机。
例如,一个应用程序依赖30个服务,每个服务99.99%的时间是运行正常的,那么可以推算出如下情况:
99.9930 = 99.7% 安全运行时间
如果服务有10亿的请求,那么 0.3% = 3,000,000 次故障
即使每个所有的依赖服务都有如此出色的正常运行时间,但是每个月依旧会有2个小时以上的宕机时间
在现在情况中恐怕会更糟糕(大部分应用都不具备99.99%正常运行时间)。即使每个服务都有着很好的表现,但是当依赖数增加,故障的几率就会被放大,以至于应用停机。
四、Hystrix 的工作原理
- 防止单个依赖服务耗尽整个容器(例如:tomcat,jboss等)用户线程
- 减少负载并快速失败,而不是排队(之间断路,而不是等待恢复)。
- 在允许的情况下提供备用机制,保护用户免受故障影响。
- 使用隔离技术 (例如隔离, 泳道, 断路) 去限制一个依赖服务故障带来的影响
- 通过近实时指标,监视和警报优化发现时间
- 通过在Hystrix的大多数方面中以低延迟传播配置更改来优化恢复时间,并支持动态属性更改,这使您可以通过低延迟反馈环路进行实时操作修改。
- 防止整个服务集群执行失败,而不仅仅是网络请求的失败(网络阻塞)。
熔断
当某个服务发生故障之后,通过熔断的故障监控,向调用方返回一个服务预期的,可处理的备选响应,而不是长时间的等待或抛出调用方法无法处理异常,这样保证了服务调用方的线程不会被长时间占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩,称之为服务降级。
该框架的目标在与通过控制访问远程系统,服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力
程序bug,数据不匹配,响应时间过长,服务不可用等等,都可能导致服务雪崩
降级
某个微服务响应时间过长,发送异常,或者不可用了,我们不能把错误错信返回回来,或者让它一直卡那那里所以要准备一个对应的策略(一个方法),当发生这种问题是,我们直接调用这个备用的方法来快速返回一个默认的结果,让请求得到快速响应,而不是一直卡在那里;
请求限流
五、项目配置
-
增加jar包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
-
启动类注解 @EnableCircuitBreaker 或 @EnableHystrix 或 @EnableHystrix 推荐@EnableHystrix 清晰明了
-
启动熔断降
-
方法上增加如下注解
@HystrixCommand(fallbackMethod = “fallback”) // 加入@HystrixCommand注解实现断路器功能如果调用的方法发生异常,或者调用其他服务失败则会直接返回fallback方法中内容,直接服务降级
hystrix 默认超时时间是1000毫秒,如果响应超过此时间就会触发熔断器
-
-
yml配置文件中常用配置,更多配置
hystrix: command: default: execution: timeout: # 启用超时设置(默认是true) enabled: true isolation: thread: # 熔断时间为1S timeoutInMilliseconds: 1000 # 超时时是否熔断 interruptOnTimeout: true # 取消时是否熔断 interruptOnCancel: false # 隔离策略:THREAD(线程方式),Semaphore(信号量,类似令牌) strategy: THREAD semaphore: # 线程最大并发数,默认10,使用Semaphore隔离策略才生效 maxConcurrentRequests: 200 threadpool: default: # 核心线程数100 coreSize: 100
-
方法配置
// 常规方法 @RequestMapping(value="test") public Result test1() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return ResultUtils.wrapSuccess(); } // 方法上配置的超时时间等信息优先级高于配置文件中配置 @HystrixCommand(fallbackMethod = "fallback", commandProperties= { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) @RequestMapping(value="testHystrix") public Result testHystrix() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return ResultUtils.wrapSuccess(); } public Result fallback () { return ResultUtils.wrapFail("服务降级"); }
-
降级方法中捕获异常和忽略异常
/** * 方法上配置的超时时间等信息优先级高于配置文件中配置 * 降级方法中捕获异常,并成功返回 * @return */ @HystrixCommand(fallbackMethod = "fallback", commandProperties= { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) @RequestMapping(value="testHystrix") public Result testHystrix() { String mes = null; if(mes == null){ throw new RuntimeException("服务异常"); } return ResultUtils.wrapSuccess(); } public Result fallback (Throwable throwable) { throwable.printStackTrace(); System.out.println(throwable.getMessage()+"异常消息"); return ResultUtils.wrapFail("服务降级"); } /** * 方法上配置的超时时间等信息优先级高于配置文件中配置 * ignoreExceptions 降级方法忽略的异常,不会被降级方法捕获,原方法直接抛出异常 */ @HystrixCommand(fallbackMethod = "fallback", commandProperties= { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") },ignoreExceptions = Throwable.class ) @RequestMapping(value="testHystrixException") public Result testHystrixException() { String mes = null; if(mes == null){ throw new RuntimeException("服务异常"); } return ResultUtils.wrapSuccess(); } public Result fallbackException () { return ResultUtils.wrapFail("服务降级"); }
六、降级作用
-
可以监听请求是否超时(默认1s)
-
异常或者报错可以快速返回,不会一直等待,或者直接页面展示异常信息(避免线程累积导致服务宕机)
-
当系统马上迎来大量的并发(双11秒杀或促销)此时如果系统承载不了这么大的并发,可以考虑关闭一些不重要的微服务(在降级方法中,返回一个友好的提示),把资源让给核心微服务,待高峰流量过去,在开启回来
七、 服务限流
/**
* threadPoolKey:标识,hystrix使用此标识计数
* coreSize:核心线程池数大小
* maxQueueSize:最大队列大小
*
* 线程中最多有2个,队列中存储一个等待,最多处理3个请求,
* 当并发处理4个请求时则会直接限流处理
* 比如如下方法中 在2s内请求超过3个剩余的请求全部降级处理,达到限流的作用
*/
@HystrixCommand(fallbackMethod = "fallbackTraffic",
threadPoolKey = "traffic",threadPoolProperties = {
@HystrixProperty(name = "coreSize",value = "2"),
@HystrixProperty(name = "maxQueueSize",value = "1")
}
)
@RequestMapping(value="testHystrixTraffic")
public Result testHystrixTraffic() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ResultUtils.wrapSuccess();
}
public Result fallbackTraffic () {
return ResultUtils.wrapFail("服务降级");
}
八、 服务监控方案
-
Spring Cloud hystrix dashboard仪表盘
- 单一服务监控
-
Spring Cloud hystrix turbine
- 多个服务监控
参考原文
https://blog.csdn.net/tongtong_use/article/details/78611225
https://www.pianshen.com/article/81401272040/