美文网首页
SpringCloud系列之负载均衡Ribbon·8-如何针对具

SpringCloud系列之负载均衡Ribbon·8-如何针对具

作者: 那钱有着落吗 | 来源:发表于2021-04-22 09:14 被阅读0次

前面我们一直在学习负载均衡策略,话说条条大路通罗马,既然Ribbon提供了这么多的策略,我该用哪个策略才好呢

比如说,我们开发了一个库存补货接口,每次调用后就自动补货上架100个商品。假如这个接口发生了超时,调用方收到timeout异常,但实际上库存服务在后台还在执行,只不过最终结果无法通知到调用方。也就是说实际补货成功,但调用方那边却超时了。
在上面这种情况下,如果一次次不停重试,可能你马上就要爆仓了。之所以类似的服务不能进行retry的原因,在于接口没有实现幂等性。

幂等性往往针对的是执行“update”操作的接口,也就是常说的“写”操作。简单理解就是对一个具备幂等性的接口进行一次请求调用,和多次请求调用(每次调用的参数也相同),在执行结果上没有区别,接口并不会因为多调用了几次就产生不同结果。因此就需要从业务层面和代码层面做资源检查或锁定,来保证幂等性,这也是目前常用的分布式事务TCC方案的核心知识点。

用时间换空间?

在魔都买房子就得采取“用时间换空间”的策略,甭管老破小先上车再说,过个几年再换个大house。在Ribbon这里,时间和空间经常要被换来换去,时间代表着接口响应时间(下文简称RT:Response Time),空间表示服务器的可用连接数。

在Ribbon里有两个和时间与空间密切相关的负载均衡策略,BestAvailableRule(简称BA)和WeightedResponseTimeRule(简称WRT)。他们都有同一个梦想,那就是希望世界和平,那就是选择压力较小的服务节点,但这两个策略努力的方向不同。BA会根据服务节点过去一段时间的请求数,选择并发量最小的机器(选择空间);WRT则是根据响应时间的统计结果,选择响应时间最快的服务(选择时间)。

我们知道服务的RT受很多因素制约,服务本身响应时间,网络连接时间,容器状态甚至JVM的full GC等等都会影响最终的RT。我们来设想这样一个场景,现在有一个非常轻量级的微服务,他的业务代码耗时大概在2ms范围内,只占整个接口响应时间的20%,而剩下80%基本都用在了网络连接的开销上。

在上面这个例子中,如果我们以RT作为指标,其实并不能客观获取服务节点当前的性能数据,因为接口本身的处理时间在RT分布中只占有很小的比例,甚至短时间的网络抖动都会对RT采样造成很大影响。而由于接口响应时间较短,因此性能瓶颈更容易被连接线程数卡住。线程数量达到上限会延长新请求的等待时间,从而增加RT,但这种情况下active的线程数量有更灵敏的指示作用,因为等到RT显著增加的时候,线程池可能早已被吃满了。对待这类问题,我们的实践经验是:

    1. 连接数敏感模型 对响应时间较短,或RT和业务复杂度是非线性相关关系的接口,采用基于可用连接数的负载均衡策略更加合适
      同样的,假设某个接口比较重量级,接口的处理时间与接收到的参数强相关。打个比方,订单导出服务,如果发起10个请求,每个请求都需要导出当前用户过去一整年的订单数据,那么这10个请求都会耗费大量的系统资源(CPU,内存)参与业务,同时RT时间也会相应拉长。在另一台机子上,同样是10个请求,但是只需要导出1个月的数据,相比较第一台机器,连接数相等的情况下,系统资源的占用率却大大不同。在这样的场景下,基于RT的指标具有更高的敏感度,我们的实践经验是:
    1. RT敏感模型 对重量级接口,尤其是根据参数不同会导致系统资源使用率浮动较大的接口(RT与业务复杂度线性相关),建议采用基于响应时间的负载均衡策略。

当断则断

假如集成了Hystrix熔断器,而当前服务正处于熔断状态,你还想往火坑里跳吗?这时我们就需要根据熔断状态做过滤,使用AvailabilityFilteringRule便是极好的。

相关文章

网友评论

      本文标题:SpringCloud系列之负载均衡Ribbon·8-如何针对具

      本文链接:https://www.haomeiwen.com/subject/betzlltx.html