在集中式環境中服務的機器臺只有一臺,這樣對於服務不僅存在服務單點故障問題而且還存在流量問題。爲了解決這個問題,就引入的分佈式與集羣概念。
分佈式:一個業務分拆多個子業務,部署在不同的服務器上
集羣:同一個業務,部署在多個服務器上
1、 dubbo 服務治理
當請求來臨時,如何從多個服務器中,選擇一個有效、合適的服務器,這個集羣所需要面對一問題。所以在集羣裏面就引申出負載均衡(LoadBalance),高可用(HA),路由(Route)等概念。我們來看一下 dubbo 在進行服務調用的時候是如何處理的。
這張集羣容錯包含以下幾個角色:
Invoker
:對Provider
(服務提供者) 的一個可調用 Service 接口的抽象,Invoker
封裝了Provider
地址及Service
接口信息。Cluster
:Directory
中的多個Invoker
僞裝成一個Invoker
,對上層透明,僞裝過程包含了容錯邏輯,調用失敗後,重試另一個Directory
:代表多個Invoker
,可以把它看成List<Invoker>
,但與 List 不同的是,它的值可能是動態變化的,比如註冊中心推送變更Router
: 負責從多個Invoker
中按路由規則選出子集,比如讀寫分離,應用隔離等LoadBalance
:LoadBalance
負責從多個Invoker
中選出具體的一個用於本次調用,選的過程包含了負載均衡算法,調用失敗後,需要重選.
2、 目錄服務
下面我們來分析一下 Directory, 也就是目錄服務。我們可以來看一下 維基百科, 對於目錄服務的描述。
在計算中,目錄服務或名稱服務將網絡資源的名稱映射到它們各自的網絡地址。它是一個共享的信息基礎設施,用於定位、管理、管理和組織日常項目和網絡資源,這些資源包括卷、文件夾、文件、打印機、用戶、組、設備、電話號碼和其他對象。目錄服務是網絡操作系統的關鍵組件。目錄服務器是提供此類服務的服務器。網絡上的每個資源都被目錄服務器視爲對象。關於特定資源的信息存儲爲與該資源或對象相關聯的屬性集合。
目錄服務爲網絡定義一個名稱空間。名稱空間用於爲每個對象分配名稱(惟一標識符)。目錄通常有一組規則來決定如何命名和識別網絡資源,這通常包括一個要求,標識符是唯一的和明確的。在使用目錄服務時,用戶不需要記住網絡資源的物理地址;提供一個名稱來定位資源。有些目錄服務包括訪問控制條款,限制了對授權用戶的目錄信息的可用性。
3、Directory
下面我們來看一下 Directory 接口的定義:
public interface Directory<T> extends Node {
/**
* get service type.
*
* @return service type.
*/
Class<T> getInterface();
/**
* list invokers.
*
* @return invokers
*/
List<Invoker<T>> list(Invocation invocation) throws RpcException;
}
集羣調用的時候可以通過目錄服務的list
方法獲取到 Invoker 列表,它有兩種具體的實現:
3.1、StaticDirectory
StaticDirectory :靜態目錄,它的 Invoke 列表是通過構造器傳入。服務消費方在引用服務的時候把多註冊中心暴露的 Invoke 以構造器的形式傳入到 StaticDirectory,然後再由 Cluster 僞裝爲一個 Invoke 提供給服務消費方調用。
StaticDirectory 的 list 方法直接返回所有 invoker 集合。
3.2、RegistryDirectory
RegistryDirectory:註冊目錄服務,實現 NotifyListener 接口。當有服務註冊到註冊中心上面,會動態更新到註冊目錄服務裏面。
消費方調用某個遠程服務,會向註冊中心訂閱這個服務的所有服務提供方。當服務提供方的數據有變動時就會回調消費方RegistryDirectory#notify
把傳入的所有服務提供方的 URL 地址轉換爲 Invoker 列表。
這樣就起到了服務治理中的服務自動發現。