您好,登錄后才能下訂單哦!
這篇文章主要講解了“Ribbon中BestAvailableRule和RetryRule的使用方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Ribbon中BestAvailableRule和RetryRule的使用方法”吧!
Ribbon的版本是2.3.0.release.
圖1
ClientConfigEnabledRoundRobinRule如下所示,定義了一個類屬性RoundRobinRule,choose方法中調用RoundRobinRule進行選擇,所以這里面的是輪循算法。
List-1.1
public class ClientConfigEnabledRoundRobinRule extends AbstractLoadBalancerRule { RoundRobinRule roundRobinRule = new RoundRobinRule(); public ClientConfigEnabledRoundRobinRule() { } public void initWithNiwsConfig(IClientConfig clientConfig) { this.roundRobinRule = new RoundRobinRule(); } public void setLoadBalancer(ILoadBalancer lb) { super.setLoadBalancer(lb); this.roundRobinRule.setLoadBalancer(lb); } public Server choose(Object key) { if (this.roundRobinRule != null) { return this.roundRobinRule.choose(key); } else { throw new IllegalArgumentException("This class has not been initialized with the RoundRobinRule class"); } } }
BestAvailableRule繼承了ClientConfigEnabledRoundRobinRule,內部實現如下List-1.2,遍歷所有的服務提供者,選擇并發量最小的那個服務。
List-1.2
private LoadBalancerStats loadBalancerStats; public Server choose(Object key) { if (this.loadBalancerStats == null) { return super.choose(key); } else { List<Server> serverList = this.getLoadBalancer().getAllServers(); int minimalConcurrentConnections = 2147483647; long currentTime = System.currentTimeMillis(); Server chosen = null; Iterator var7 = serverList.iterator(); while(var7.hasNext()) { Server server = (Server)var7.next(); ServerStats serverStats = this.loadBalancerStats.getSingleServerStat(server); if (!serverStats.isCircuitBreakerTripped(currentTime)) { int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); if (concurrentConnections < minimalConcurrentConnections) { minimalConcurrentConnections = concurrentConnections; chosen = server; } } } if (chosen == null) { return super.choose(key); } else { return chosen; } } } public void setLoadBalancer(ILoadBalancer lb) { super.setLoadBalancer(lb); if (lb instanceof AbstractLoadBalancer) { this.loadBalancerStats = ((AbstractLoadBalancer)lb).getLoadBalancerStats(); } }
choose方法重新了父類中的choose方法,
獲取服務列表,遍歷服務
通過ServerStats獲取當前服務實例的并發連接數,如下List-3所示,并發連接數不是0,且當前時間與上次有效更改時間間隔在范圍內,則返回當前并發連接數。
遍歷所有的服務提供者后,如果得到的server是null,則調用父類的choose方法,用RoundRobin算法進行選擇。
List-1.3
public int getActiveRequestsCount(long currentTime) { int count = this.activeRequestsCount.get(); if (count == 0) { return 0; } else if (currentTime - this.lastActiveRequestsCountChangeTimestamp <= (long)(activeRequestsCountTimeout.get() * 1000) && count >= 0) { return count; } else { this.activeRequestsCount.set(0); return 0; } }
圖2
RetryRule的實現比較簡單,基于RoundRobinRule,如下List-2.1所示
List-2.1
public class RetryRule extends AbstractLoadBalancerRule { IRule subRule = new RoundRobinRule(); long maxRetryMillis = 500L; ... public Server choose(ILoadBalancer lb, Object key) { long requestTime = System.currentTimeMillis(); long deadline = requestTime + this.maxRetryMillis; Server answer = null; answer = this.subRule.choose(key); if ((answer == null || !answer.isAlive()) && System.currentTimeMillis() < deadline) { InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis()); while(!Thread.interrupted()) { answer = this.subRule.choose(key); if (answer != null && answer.isAlive() || System.currentTimeMillis() >= deadline) { break; } Thread.yield(); } task.cancel(); } return answer != null && answer.isAlive() ? answer : null; } ...
RetryRule中choose(Object key)調用choose(ILoadBalancer lb, Object key),
當前時間加上maxRetryMillis得到deadline,即截止時間
用subRule獲取服務server,如果服務有效則直接返回該服務
構造InterruptTask,它里面有個Timer定時任務,如List-2.2。之后循壞,只要當前線程沒有被interrupt,則用subRule的RoundRobin算法選擇一個服務實例,如果這個服務有效或者當前時間過了截止時間則跳出循壞
如果步驟3中得到的服務實例無效,且當前時間在截止時間之內,則調用Thread.yield(),讓出線程資源給其它線程
通過源碼可知,RetryRule在subRule.choose獲得無效的服務實例后,僅僅是再次再次用subRule獲取服務實例,并不會一直嘗試下去,即嘗試一次。
List-2.2
public class InterruptTask extends TimerTask { static Timer timer = new Timer("InterruptTimer", true); protected Thread target = null; public InterruptTask(long millis) { this.target = Thread.currentThread(); timer.schedule(this, millis); } public boolean cancel() { try { return super.cancel(); } catch (Exception var2) { return false; } } public void run() { if (this.target != null && this.target.isAlive()) { this.target.interrupt(); } } ...
感謝各位的閱讀,以上就是“Ribbon中BestAvailableRule和RetryRule的使用方法”的內容了,經過本文的學習后,相信大家對Ribbon中BestAvailableRule和RetryRule的使用方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。