zoukankan      html  css  js  c++  java
  • Robin负载均衡策略存在问题及CSE解决方案

    【摘要】 本文描述了CSE在使用Ribon组件期间发现的问题,以及CSE是如何解决这些问题以满足自身业务开发需要的。

    Robin

    Robin设计了几个核心接口:IRule、ILoadBalancer、ServerListFilter、IPing、ServerList、Server。开发者在使用的时候,需要组合使用这些接口。Robin提供了大量的接口实现,在使用这些实现或者自定义实现的时候,存在非常多的问题需要考虑:

    1.       每一个实现类依赖的其他接口的功能是不确定的,不能够随意组合。比如:ServerListFilter只会被DynamicServerListLoadBalancer使用,而不会被ILoadBalancer的其他实现类使用;IRule的不同实现,依赖的ILoadBalancer接口不同,RoundRobinRule会调用getAllServerList,并且会判断返回的Server是否alive,而RandomRule则不会使用这些接口,这种情况会给实现ILoadBalancer的开发人员带来大量的困扰,他们必须对每一个可能的IRule实现进行测试,以保证提供给用户的功能说明是可靠的。这种情况带来的另外问题,就是限制了运维人员在运行时动态的调整负载均衡策略。使用Robin组件,更加适用于开发阶段确定好各个实现,而不进行修改。

    2.       在使用ServerListFilter的时候,不能够基于每次请求的参数进行实例过滤。这样类似灰度发布等功能无法通过它实现。因为ServerListFilter会通过ILoadBalancer获取当前请求参数,而ILoadBalancer则被大量的请求共用。业务必须通过ThreadLocal来保存请求参数,以防止并发问题。初次使用这种机制的业务基本都会忽略这个问题,必须通过大量并发测试才可能发现,很多时候会将问题遗漏到生产环境。

    3.       在需要动态调整IRule的场景,部分IRule的实现可能会导致内存泄露。比如WeightedResponseTimeRule。这个规则在初始化的时候,会启动Timer线程计算权重,并且每次更新ILoadBalancer的时候(调用setLoadBalancer方法),会重新初始化,如果并发控制不当,则会导致频繁创建线程造成OOM。这个问题需要在进行大量并发和持续运行的情况下才能够发现。

    总结:Robin定义了很灵活的接口,在实现单一场景的时候,可以满足非常多场景的需求。但是在动态调整策略、自由组合策略以及定制开发过程中都存在大量的陷阱,需要开发人员非常谨慎使用,有些陷阱需要进行大量并发和长时间运行才能够发现。

    CSE对负载均衡算法的改进

    CSE结合自身对负载均衡的理解,对负载均衡处理流程进行了改进。下面是流程图:

    image.png

    1.       DiscoveryFilter主要管理实例进行分组、缓存。详细流程参考:https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html

    2.       对每一个微服务分配一个LoadBalancer实例。

    3.       ServerListFilerExt和RuleExt均对Robin的ServerListFilter和IRule进行了改进。参数增加了Invocation,这样可以支持基于接口参数的路由选择。对于ServerListFilter和IRule的扩展,都只需要实现接口,并不需要依赖大量的LoadBalancer的接口,这样就避免了业务在实现这些接口的时候,需要考虑组合的一致性,减少业务犯错误的风险。

    4.       整改以后,业务不能在随意配置和使用IRule和ServerListFilter的实现。需要使用系统缺省的配置参数:RoundRobin、Random、SessionStickiness、WeightedResponse等,这些字符串表达和实现方式独立。业务也可以通过扩展ExtensionFactory实现自己的RuleExt和ServerListFilterExt。

    基于响应时间权重问题

    经过上述整改,CSE重新实现了WeightedResponseTimeRule,新实现的算法没有采用定时器和新线程,可以避免频繁替换Rule和并发场景下可能导致的内存泄露等问题。这个算法存在如下需要注意的问题:

    1.       “权重”和“响应时间”并不是一个严格意义上的反比关系。比如时延为20ms和40ms,并不意味着实例选择的概率是2:1。目前计算“权重”和“响应时间”的算法为:

    T = SUM(L1,L2,…,Ln)

    (L1:L2:…:Ln) = (T-L1:T-L2:…:T-Ln)=(W1:W2:…:Wn)

    “权重算法”是一个伪随机算法,实例的分布符合上述的公式,但是每次选中的实例是不可预期的。 另外,如果所有实例的响应时间均小于10ms,那么权重算法等同于RoundRobin算法。

    2.       在实例数为100的情况下,基于响应时间权重算法比RoundRobin算法慢100倍。但是不用担心,这个是对实例列表遍历一遍的时间,在业务处理时间为10ms的情况下,只占用业务1/1000的时间。

    来源:华为云社区  作者:liubao68

     

  • 相关阅读:
    Unity5和WebGL移植指南的一些总结
    Unite洛杉矶峰会精彩回顾:从图形、平台再到VR
    比代码更重要的是团队管理
    初期游戏编程的9大法则
    关于Unity3D手机网游开发一些小看法
    守住真我
    学习要讲方法
    学习笔记|编程风格
    随便记
    微信方法
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13165866.html
Copyright © 2011-2022 走看看