重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
本篇內容介紹了“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的使用方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯網站,小編將為大家輸出更多高質量的實用文章!