springCloud----hystrix

原创
2021/03/04 21:40
阅读数 87

从理论层面上来讨论超时、重试、熔断、限流、降级等。

1.超时

在接口调用过程中,consumer调用provider的时候,如果provider在响应的时候有延迟,即provider响应10s,那么consumer也至少会等待10s,如果这种情况频度很高,那么就会整体降低consumer端服务的性能。同时,如果consumer的上层调用consumer,那么这样就会一层又一层的延迟,导致最上层的应用超时。 所以每层consumer不能无限制等待provider,会设置一个阈值,如果超过了这个阈值,就不会在继续等待。这个阈值的设置一般取provider正常响应时间值+buffer值。

2.重试

超时设置是为了保护上层应用,但也有可能是provider网络抖动,如果超时后直接放弃,不做后续处理,则会导致当前请求错误,给业务层面带来损失。 那么对于这种抖动情况,可以在超时后重新请求一下,重试如果正常返回了,那么这次请求就被挽救了,只不过比原来响应慢一点。 重试时采用一些优化策略:重试时可以考虑切换一台机器来调用,因为原机器可能由于临时负载高而导致性能下降。

2.1幂等

如果允许consumer重试,那么provider就要做到幂等。即:同一个请求被consumer多次调用,对provider产生的影响(指的是写操作影响)是一致的。而且这个幂等应该是服务级别的,而不是某台机器层面的,重试调用任何一台机器,都应该做到幂等。

3.熔断

重试是为了应付偶尔抖动的情况,以求更多的挽回损失。如果重试过程中,provider一直响应时间超时,那么这个时候就要采取熔断措施了,即consumer调用provider的请求,直接短路掉,同时直接返回一个mock值(即组装返回对象的值)。我们实际场景:app端调用后端A服务,A服务去调用B服务,发现B服务超时了,则A服务重试一次,B服务依然超时,那这个时候就要采取熔断策略,直接返回mock值或者从A服务的本地缓存中取出数据。

4.限流

如上几个策略都是针对provider端出现问题设计的。而provider端有时候也要防范来自consumer端流量突变的问题。 有这样一个场景,provider是一个核心服务,给N个consumer提供服务,突然某个consumer端流量飙升,这样就会给provider端造成很大压力,甚至会导致provider无法正常工作。那么,provider端需要根据consumer端的重要程度,以及平时的QPS,来给每个consumer设置一个流量上限,同一个时间段只会给consumer端提供N个线程支持,超过限制要么等待要么直接拒绝。 基于Redis的限流方案:假设限制每个用户(用IP判断)每分钟访问某个接口的次数不超过10次,则我们可以在Redis中创建一个key(存放ip值),key的TTL设置成60s,value存放访问次数,初始值为0,每个用户访问一次接口就将value值加1,在60s内当value值加到10的时候,该用户禁止访问该接口。

5.资源隔离

我们都知道计算机资源是有限的,比如CPU、内存、队列、线程池都是资源,他们都有限定的资源数,如果不进行隔离,一个服务的调用可能会消耗很多的线程资源,把其它服务的资源都占用了,那么可能会出现一个服务的问题而拖垮其它服务。

6.降级

当某个服务出现问题影响到核心流程的性能时,则需要对服务降级,即临时关闭一些不重要的服务。如果所有的服务都不能关闭的时候,则需要采取限流手段。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部