在學習Ribbon以前,先看一下這張圖,這張圖完美的把Ribbon的基礎架構給描述出來了架構
這張圖的核心是負載均衡管理器,圍繞着它的是外面的這5大功能點,我們就從核心開始看而後再帶出來其餘的功能併發
首先看一下負載均衡器的核心接口ILoadBalancer
負載均衡
public interface ILoadBalancer { public void addServers(List<Server> newServers); public Server chooseServer(Object key); public void markServerDown(Server server); public List<Server> getReachableServers(); public List<Server> getAllServers(); }
這個接口中保護了一個基本的負載均衡器所必須的全部功能:dom
addServers(List)
向負載均衡器中添加服務實例chooseServer(Object)
根據負載均衡策略,從負載均衡器中挑選出一個服務實例markServerDown(Server)
下線負載均衡器中的某個具體實例getReachableServers()
返回當前可正常服務的實例列表getAllServers()
返回全部的服務實例列表接着來看一下這個接口的UML圖
學習
首先看AbstractLoadBalancer
這個類,這個類是ILoadBalancer
接口的抽象類實現。
在這個抽象類中定義了一個表示服務實例狀態的枚舉的同時還新增了兩個抽象方法:url
public enum ServerGroup{ ALL, STATUS_UP, STATUS_NOT_UP } public abstract List<Server> getServerList(ServerGroup serverGroup); public abstract LoadBalancerStats getLoadBalancerStats();
getServerList(ServerGroup)
:根據分組類型來返回不一樣的服務實例列表。getLoadBalancerStats()
:返回LoadBalancerStatus
對象,這個LoadBalancerStats
對象是用來存儲負載均衡器中各個服務實例當前的屬性和統計信息的AbstractLoadBalancer
共有兩個實現類,右側的NoOpLoadBalancer
是一個空的實現類,這裏能夠忽略不計。這裏接着繼續看BaseLoadBalancer
線程
BaseLoadBalancer
是負載均衡器的基礎實現類,這個類對於接口ILoadBalancer
的全部方法都給予了基礎的實現,除此以外還保護了不少重要的對象code
兩個存儲當前服務實例對象的列表,一個是包含全部服務、一個是包含正常服務server
@Monitor(name = PREFIX + "AllServerList", type = DataSourceType.INFORMATIONAL) protected volatile List<Server> allServerList = Collections .synchronizedList(new ArrayList<Server>()); @Monitor(name = PREFIX + "UpServerList", type = DataSourceType.INFORMATIONAL) protected volatile List<Server> upServerList = Collections .synchronizedList(new ArrayList<Server>());
存儲負載系統器各服務實例屬性和統計信息的對象對象
protected LoadBalancerStats lbStats;
protected IPing ping = null;
IPing
是用來向服務發起心跳檢測的,經過心跳檢測來判斷該服務是否可用。IPing
的實現類有如下幾種:
PingUrl
:使用HttpClient去get請求某個url,判斷其是否alivePingConstant
:固定返回某服務是否可用,默認返回trueNoOpPing
:沒有任何操做,直接返回trueDummyPing
:一樣是直接返回trueNIWSDiscoveryPing
:根據服務的實例對象InstanceInfo
的InstanceStatus
去判斷,若是爲InstanceStatus.UP,則爲可用心跳檢測策略對象IPingStrategy
private final static SerialPingStrategy DEFAULT_PING_STRATEGY = new SerialPingStrategy(); protected IPingStrategy pingStrategy = DEFAULT_PING_STRATEGY;
默認實現是線型輪詢
private final static IRule DEFAULT_RULE = new RoundRobinRule(); protected IRule rule = DEFAULT_RULE;
IRule
是在選擇實例的時候的負載均衡策略對象,默認使用的是RoundRobinRule
線性輪詢
除此以外的實現爲:
BestAvailableRule
:選擇最小請求數RandomRule
:隨機選擇RetryRule
:輪詢重試WeightedResponseTimeRule
:根據響應時間分配權重ZoneAvoidanceRule
:根據服務的分區可用性輪詢如今繼續看BaseLoadBalancer
的子類DynamicServerListLoadBalancer
這個類對基礎負載均衡器作了擴展。擴展的功能以下:
public interface ServerList<T extends Server> { /** * 獲取初始化的服務列表 */ public List<T> getInitialListOfServers(); /** * 獲取更新後的服務列表 */ public List<T> getUpdatedListOfServers(); }
在DynamicServerListLoadBalancer
中默認使用的服務列表實現類是DomainExtractingServerList
,只不過該服務列表內部還定義了一個服務列表,這個服務列表的實現類則是DiscoveryEnabledNIWSServerList
這個最終的服務列表的數據來源則主要依靠EurekaClient從註冊中心獲取
這個接口定義了一系列的對服務列表的更新操做
public interface ServerListUpdater { //內部接口 public interface UpdateAction { //實現對服務列表的更新操做 void doUpdate(); } //啓動服務更新器 void start(UpdateAction updateAction); //中止服務更新器 void stop(); //返回最近的更新時間戳 String getLastUpdate(); //返回上一次更新到如今的時間間隔(ms) long getDurationSinceLastUpdateMs(); //返回錯過的更新週期數 int getNumberMissedCycles(); //返回核心線程數 int getCoreThreads(); }
它的實現類有兩個:
PollingServerListUpdater
:經過定時任務進行更新EurekaNotificationServerListUpdater
:利用Eureka的事件監聽器來更新public interface ServerListFilter<T extends Server> { public List<T> getFilteredListOfServers(List<T> servers); }
該接口主要用於根據一些規則過濾傳入的服務實例列表,該接口的實現類以下:
ZoneAffinityServerListFilter
:基於Eureka的分區規則對服務實例的過濾DefaultNIWSServerListFilter
:ZoneAffinityServerListFilter
的子類且沒有作特殊的更新ServerListSubsetFilter
:經過比較服務實例的通訊失敗數和併發鏈接數來剔除那些相對不夠健康的實例ZonePreferenceServerListFilter
:使用SpringCloud整合eureka和ribbon時默認使用的該過濾器。它實現了經過配置或eureka實例無數據的所屬區域(Zone)來過濾出同區域的服務實例ZoneAwareLoadBalancer
則是對DynamicServerListLoadBalancer
的擴展,它主要增長了區域過濾的功能