Hystrix
什么是服务雪崩?
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的 “扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的”雪崩效应“。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
所以通常当发现某个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
1.1.Hystrix是干嘛的
Hystrix是一个用于处理分布式系统的延迟和容错的一个开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的稳定性。“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的,可处理的备选响应,而不是长时间等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
1.2.服务降级(Fallback)
1.2.1什么是服务降级
假设对方系统不可用了,向调用方返回一个符合预期的,可备选的响应。服务器忙,请稍后重试,不让客户等待并立刻返回一个友好的提示,这就是服务降级。就像if( ){ }else if{}....有备选方案。再比如给10086打电话,客服繁忙...
出现服务降级的情况:
- ①程序运行异常;
- ②超时;
- ③服务熔断触发服务降级;
- ④线程池/信号量打满也会导致服务降级。
1.2.2进行服务降级的情况
用jmeter进行压力测试,开启20000个线程进行测试,测试服务端8001环境下的两个地址,结果发现不仅压测访问的地址变慢,同一微服务下的另一个地址访问也变慢了,假设客户端80访问,一定会更慢,那样客户端一定会很不满意。那就来试一下,让客户端访问:8001同一层次的其它接口服务被困死(20000个线程访问),因为tomcat线程池里面的工作线程已经被挤占完毕,80此时调用8001,客户端访问响应会变慢,转圈圈。正是因为这些故障和不佳表现,才有我们的降级、容错、限流等技术的产生。
解决要求:
- 超时导致服务器变慢(转圈):超时不再等待;
- 出错(宕机或程序运行出错):出错要有兜底。
1.2.3解决方案
对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级;对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须服务降级;对方服务(8001)OK(可能),调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级。
1.2.4如何启用服务降级
image①服务端做降级:首先在业务类中加入新的配置标签@HystrixCommand,相当于在fallbackMethod中添加一个方法,如下value设置为3s,当超过3秒时,就会调用备用的方法,或者是方法中运行错误,比如说是以下的10/0报错。
②然后在主启动类中加入@EnableCircuitBreaker,这样就可以在服务提供端测试自己的服务降级了
而一般Hystrix服务降级fallback是放在客户端的,步骤如下:
image①首先在yml加上hystrix和feign的配置
②在主启动类中添加注解@EnableHystrix
image③在业务类中利用Hystrix实现服务降级就行了,跟服务提供端类似。在这里消费者端的服务降级时间设置的是1.5秒,而上面服务端设置的时间是3s,加入服务端线程运行时间实际花费了2秒,在客户端照样会发生服务降级,而以下10/0在会直接进行降级。
上面的方法是利用openfeign直接调用服务端提供的方法。是前面学习过的。
image1.2.5设置全局通用服务降级方法
image目前存在的问题,每个业务方法都会有一个兜底的方法,会导致代码膨胀,可以设置一个全局通用的服务降级兜底的方法,如果需要特殊配置的在另外配。需要加入一个新的注解:DefaultProperties(defaultFallback=" ")统一跳转到处理结果页面。这样可以使得代码量大大减少。首先在类上加上新的注解,其他的方法没有设置fallback属性的话,就会进入全局fallback方法。
image就像这样,下面的方法只添加了@HystricCommand注解,如果出现异常就会进入payment_global_fallback兜底方法。
1.2.6通配服务降级
image image image目前来看,耦合度太高,在controller中要声明很多兜底的方法以备用,可以从源头来解决这个问题,在这里使用的feign调用的服务端提供的方法,可以直接在这个调用类里进行解决,如下:写一个fallback的类直接实现这个接口,一旦这个接口中的某个方法出现了问题,会直接调用实现类中的方法。如果发生运行、超时、宕机异常都会导致降级,而下面的paymentinfo_OK在其他地方没有配置降级方法,如果8001宕机,一定会调用下面实现类的paymentinfo_OK方法。
1.3服务熔断(break)
类似保险丝达到最大服务访问时,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。断路器就相当于是保险丝。
Hystrix结构图 image熔断机制的描述:熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路某个微服务出错不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回错误信息。当检测到该节点微服务调用响应正常后,恢复调用链路。熔断机制通过Hystrix实现,Hystrix会监控微服务间的调用的状况,当失败的调用到一定的阈值,缺省是5秒内20次调用失败,就会启动熔断机制,熔断机制的注解是@HystrixCommand。
断路器三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值
1、快照时间窗:
断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10s。
2、请求总数阈值:
在快照时间窗内,必须满足请求总数阈值才有资格熔断,默认为20,意味着在10s内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。
3、错误百分比阈值:
当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设置50%阈值的情况下,这时候就会将断路器打开。
如以下所示,仍然还是在HystrixCommand注解中进行配置,在上面加了四个Hystrix新的属性配置,意思就是在10s的窗口期内,发送十次请求,假如说有60%也就是6次都失败了,就激活断路器。而当他断路器激活以后,所有的请求都无法处理了,而过一段时间之后,断路器又会尝试着让少量的请求通过一下(也就是断路器进入了half-open状态),而如果请求仍然失败,断路器又会重新回到open状态,如果请求成功,断路器则会关闭。也就是链路恢复。
image在controller中写出响应的调用,然后进行访问,如果十次中有六次及以上是负数,会发现,第11次时就算是正数仍然会进入fallback方法,因为此时进行了服务熔断。
1.4服务限流:(flowlimit)
秒杀高并发的操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序的进行。
1.5 Hystrix工作流程总结
image1.6 接近实时的监控
Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续的记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求,多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
1.6.1搭建流程
①首选创建一个新的module,导入pom,主要是spring-cloud-starter-netflix-hystrix-dashboard
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
注意还有一个依赖,这个依赖如果是要进行图形化展示是一定要有的,一般和web同时存在
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
②然后配置yml
暂且配置一个端口号就够用了
image③主启动类,注意添加了一个新的注解:@EnableHystrixDashboard,一般要用一个新的功能,就要添加新的注解
image④:最后访问localhost://9001/hystrix就可以显示了
image1.6.2进一步配置以进行监控
image image imageHystrix的服务监控需要自己配置,对于传统的微服务架构一定是够用了,而spring Cloud Alibaba提供的微服务监控可以直接访问,在后面会学习到,主要进行sentienl的学习。