本篇内容介绍了“Ribbon中RandomRule和RoundRobinRule的使用方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
成都创新互联公司主要为客户提供服务项目涵盖了网页视觉设计、VI标志设计、全网整合营销推广、网站程序开发、HTML5响应式成都网站建设、手机网站开发、微商城、网站托管及成都网站维护、WEB系统开发、域名注册、国内外服务器租用、视频、平面设计、SEO优化排名。设计、前端、后端三个建站步骤的完善服务体系。一人跟踪测试的建站服务标准。已经为成都塑料袋行业客户提供了网站改版服务。
Ribbon的版本是2.3.0.release.
图1
图1所示,RandomRule继承AbstractLoadBalancerRule,调用choose(Object)时,调用内部方法choose(ILoadBalancer lb, Object key),如下List-1
List-1
public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } else { Server server = null; while(server == null) { if (Thread.interrupted()) { return null; } ListupList = lb.getReachableServers(); List allList = lb.getAllServers(); int serverCount = allList.size(); if (serverCount == 0) { return null; } int index = this.chooseRandomInt(serverCount); server = (Server)upList.get(index); if (server == null) { Thread.yield(); } else { if (server.isAlive()) { return server; } server = null; Thread.yield(); } } return server; } } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); }
通过ILoadBalancer获取所有的服务,如果服务个数是0则直返回null
调用chooseRandomInt方法,参数是服务个数,这样返回的随机值是在0与服务数之间,有趣的是出于多线程安全的考虑,使用了java.util.concurrent.ThreadLocalRandom#current来获取随机值
如果服务是alive,则返回改服务
图2
RoundRobinRule是轮循算法实现,choose(Object)方法会调用choose(ILoadBalancer lb, Object key),如下List-2所示
List-2
private AtomicInteger nextServerCyclicCounter; public RoundRobinRule() { this.nextServerCyclicCounter = new AtomicInteger(0); } public RoundRobinRule(ILoadBalancer lb) { this(); this.setLoadBalancer(lb); } public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { log.warn("no load balancer"); return null; } else { Server server = null; int count = 0; while(true) { if (server == null && count++ < 10) { ListreachableServers = lb.getReachableServers(); List allServers = lb.getAllServers(); int upCount = reachableServers.size(); int serverCount = allServers.size(); if (upCount != 0 && serverCount != 0) { int nextServerIndex = this.incrementAndGetModulo(serverCount); server = (Server)allServers.get(nextServerIndex); if (server == null) { Thread.yield(); } else { if (server.isAlive() && server.isReadyToServe()) { return server; } server = null; } continue; } log.warn("No up servers available from load balancer: " + lb); return null; } if (count >= 10) { log.warn("No available alive servers after 10 tries from load balancer: " + lb); } return server; } } } private int incrementAndGetModulo(int modulo) { int current; int next; do { current = this.nextServerCyclicCounter.get(); next = (current + 1) % modulo; } while(!this.nextServerCyclicCounter.compareAndSet(current, next)); return next; }
很重要的一个类属性是AtomicInteger nextServerCyclicCounter,通过它来实现轮循。
ILoadBalancer获取所有的服务列表
之后调用incrementAndGetModulo方法,参数是服务个数,incrementAndGetModulo方法中用CAS来实现线程安全,获得服务的下标
得到服务Server后,判断是否是alive和ReadyToServe,则返回;如果循坏了10次还没有找到,则log打印warn日志提示
这个实现是简单的轮循,没有实现有权重的RoundRibbon。
“Ribbon中RandomRule和RoundRobinRule的使用方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!