共计 2837 个字符,预计需要花费 8 分钟才能阅读完成。
dubbo 的负载均衡策略
-
RandomLoadBalance 随机调用负载均衡 默认方式
该类实现了抽象的 AbstractLoadBalance 接口, 重写了 doSelect 方法,看方法的细节就是首先遍历每个提供服务的机器,获取每个服务的权重,然后累加权重值,判断每个服务的提供者权重是否相同,如果每个调用者的权重不相同,并且每个权重大于 0,那么就会根据权重的总值生成一个随机数,再用这个随机数,根据调用者的数量每次减去调用者的权重,直到计算出当前的服务提供者随机数小于 0,就选择那个提供者!另外,如果每个机器的权重的都相同,那么权重就不会参与计算,直接选择随机算法生成的某一个选择,完全随机。可以看出,随机调用法
-
RoundRobinLoadBlance 轮询调用
轮询调用的过程主要是维护了局部变量的一个 LinkdesHashMap(有顺序的 Map)去存储调用者和权重值的对应关系,然后遍历每个调用者, 把调用者和当前大于 0 的权重值放进去,再累加权重值。还有一个全局变量的 map,找到第一个服务调用者,首先是找到每个服务的 key 值和 method,这里可以理解为标识第一个调用者的唯一 key,然后再给它对应的值保证原子性的 +1(AtomicPositiveInteger 是原子的),再对这个值取模总权重,再每次对其权重值 -1,知道它取模与总权重值等于 0 就选择该调用者,可以称之为 ” 降权取模 ”(只是一种的计算层面, 而不是真正降权)。总结:轮询调用并不是简单的一个接着一个依次调用,它是根据权重的值进行循环的。 -
LeastActiveLoadBlance 最少活跃数调用法
这个方法的主要作用根据服务的提供者的运行状态去选择服务器, 主要的思路就是遍历每个调用者,然后获取每个服务器的运行状态,如果当前运行的运行状态小于最小的状态 -1,把它保存在 leastIndexs 中的第一个位置,并且认定所有的调用者权重都相同,然后直接返回那个调用者(这里的逻辑是:找到最少活跃数(在代码层反应就是:active 的值))。如果计算出的权重值和最少的权重值相同,那么把它保存在 leastIndexs 数组里面,累加权重值,如果当前的权重值不等于初始值 firstWeight,那么就认定不是所有的调用者的权重不同。然后再遍历 lestIndexs,取权重累加值的随机数生成权重偏移量,在累减它,到它小于 0 的时候返回那个调用者。如果这些都不符合,就从 leastIndexs 随机选一个 index,返回那个调用者! -
ConsistentHashLoadBalance 一致性 Hash 算法
doSelect 方法进行选择。一致性 Hash 负载均衡涉及到两个主要的配置参数为 hash.arguments 与 hash.nodes:当进行调用时候根据调用方法的哪几个参数生成 key,并根据 key 来通过一致性 hash 算法来选择调用节点。例如调用方法 invoke(Strings1,Strings2); 若 hash.arguments 为 1(默认值),则仅取 invoke 的参数 1(s1)来生成 hashCode。
hash.nodes:节点的副本数。。dubbo 的一致性哈希通过 ConsistentHashLoadBalance 类来实现。ConsistentHashLoadBalance 内部定义 ConsistentHashSelector 类,最终通过该类进行结点选择。ConsistentHashLoadBalance 实现的 doSelect 方法来利用所创建的 ConsistentHashSelector 对象选择结点。doSelect 的实现如下。当调用该方法时,如果选择器不存在则去创建。随后通过 ConsistentHashSelector 的 select 方法选择结点。ConsistentHashSelector 在构造函数内部会创建 replicaNumber 个虚拟结点,并将这些虚拟结点存储于 TreeMap。随后根据调用方法的参数来生成 key,并在 TreeMap 中选择一个结点进行调用。上述代码中 hash(byte[]digest,intnumber)方法用来生成 hashCode。该函数将生成的结果转换为 long 类,这是因为生成的结果是一个 32 位数,若用 int 保存可能会产生负数。而一致性 hash 生成的逻辑环其 hashCode 的范围是在 0 -MAX_VALUE 之间。因此为正整数,所以这里要强制转换为 long 类型,避免出现负数。进行节点选择的方法为 select, 最后通过 sekectForKey 方法来选择结点。在进行选择时候若 HashCode 直接与某个虚拟结点的 key 一样,则直接返回该结点,如果 hashCode 落在某个节点上。若不在,找到一个最小上个的 key 所对应的结点。
变更负载均衡策略
-
xml 配置
<dubbo:serviceinterface="..."loadbalance="roundrobin"/>
- 注解方式
@Reference 中引用,然后注明 loadblance=”xx”
dubbo 容错策略 缺省模式为 failover
-
Failover Cluster:失败重试
当服务消费方调用服务提供者失败后自动切换到其他服务提供者服务器进行重试。这通常用于读操作或者具有幂等的写操作,需要注意的是重试会带来更长延迟。可通过 retries=”2″ 来设置重试次数(不含第一次)。
接口级别配置重试次数方法 <dubbo:reference retries=”2″ />,如上配置当服务消费方调用服务失败后,会再重试两次,也就是说最多会做三次调用,这里的配置对该接口的所有方法生效。当然你也可以针对某个方法配置重试次数如下:<dubbo:reference> <dubbo:method name="sayHello" retries="2" /> </dubbo:reference>
- Failfast Cluster:快速失败
当服务消费方调用服务提供者失败后,立即报错,也就是只调用一次。通常这种模式用于非幂等性的写操作。
- Failsafe Cluster:失败安全
当服务消费者调用服务出现异常时,直接忽略异常。这种模式通常用于写入审计日志等操作。
- Failback Cluster:失败自动恢复
当服务消费端用服务出现异常后,在后台记录失败的请求,并按照一定的策略后期再进行重试。这种模式通常用于消息通知操作。
- Forking Cluster:并行调用
当消费方调用一个接口方法后,Dubbo Client 会并行调用多个服务提供者的服务,只要一个成功即返回。这种模式通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2″ 来设置最大并行数。
- Boadcast Cluster:广播调用
当消费者调用一个接口方法后,Dubbo Client 会逐个调用所有服务提供者,任意一台调用异常则这次调用就标志失败。这种模式通常用于通知所有提供者更新缓存或日志等本地资源信息。
随便写点什么,然后就发布了!