多個註冊中心
1 關聯服務和多個註冊中心
1.1 全局默認註冊中心
Dubbo 註冊中心和服務的配置是獨立的。通常情況下,開發者不需要設置服務和註冊中心組件之間的關聯關係。Dubbo 框架會自動執行以下操作
- 對於所有 Service 服務,將服務地址註冊到所有全局默認註冊中心。
- 對於所有 Reference 服務,從所有全局默認註冊中心訂閱服務地址。
# application.yml (Spring Boot)
dubbo
registries
beijing Registry
address: zookeeper://#:2181
shanghai Registry
address: zookeeper://#:2182
@DubboService
public class DemoServiceImpl implements DemoService {}
@DubboService
public class HelloServiceImpl implements HelloService {}
以上以 Spring Boot 開發為例(XML 和 API 方式類似)配置兩個全局默認註冊中心,beijingRegistry 和 shanghaiRegistry,服務 DemoService 和 HelloService 將分別註冊到這兩個默認註冊中心。
除了框架上述提到的為服務自動設置全局註冊中心外,還有兩種方式可以靈活地調整服務與多個註冊中心之間的關聯關係。
1.2 設置全局默認註冊中心
# application.yml (Spring Boot)
dubbo
registries
beijing Registry
address: zookeeper://#:2181
default: true
shanghai Registry
address: zookeeper://#:2182
default: false
default
用於設置全局默認註冊中心,默認為 true
則視為全局註冊中心。未指定註冊中心 id 的服務將自動註冊或訂閱全局默認註冊中心。
1.3 顯示關聯服務和註冊中心
通過在 Dubbo 服務定義組件中添加註冊中心配置,將服務與註冊中心關聯起來。
@DubboServiceregistry = {"beijingRegistry"}
public class DemoServiceImpl implements DemoService {}
@DubboServiceregistry = {"shanghaiRegistry"}
public class HelloServiceImpl implements HelloService {}
添加上述配置後,DemoService 將只會註冊到 beijingRegistry,而 HelloService 將會註冊到 shanghaiRegistry。
2 多註冊中心訂閱
由於服務訂閱涉及到地址聚合和路由地址選擇,邏輯會比較複雜。從單個服務訂閱的角度來看,如果存在多註冊中心訂閱,可以根據註冊中心之間的地址是否聚合分為兩種場景。
2.1 多註冊中心地址不聚合
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" />
對於如上圖所示的獨立配置的註冊中心組件,預設情況下,消費者端的地址列表是完全隔離的,負載均衡地址選擇需要經過兩個步驟
- 註冊中心集群間的站點選擇,選出一個集群
- 註冊中心集群內的地址選擇,在集群內進行地址篩選
下面我們將重點討論如何控制註冊中心跨集群站點選擇,可選策略如下:隨機 (random) 每個請求隨機分配到一個註冊中心集群
在隨機過程中會有一個可用性檢查,即每個集群必須保證至少有一個地址可用才能被選中。
優先 (preferred)
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" preferred="true"/>
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" />
如果有一個配置了 preferred="true"
的註冊中心集群,所有流量都會路由到這個集群。
加權 (weighted)
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" weight="100"/>
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" weight="10" />
基於加權隨機負載均衡,上述集群之間會有大約 10:1 的流量分配。
同 Zone 優先 (same zone priority)
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" zone="hangzhou" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" zone="qingdao" />
RpcContext.getContext().setAttachment("registry_zone", "qingdao");
根據 Invocation 中攜帶的流量參數或當前節點上通過上下文 context 設定的參數,將流量精確引導至對應的集群。
2.2 多註冊中心地址聚合
<dubbo:registry address="multiple://127.0.0.1:2181?separator=;&reference-registry=zookeeper://address11?backup=address12,address13;zookeeper://address21?backup=address22,address23" />
這裡新增一個以特殊 multiple 協議開頭的註冊中心,其中
multiple://127.0.0.1:2181
沒有具體含義,只是特定格式的佔位符,地址可以任意指定reference-registry
指定要聚合的註冊中心集群列表。示例中,有兩個集群,zookeeper://address11?backup=address12,address13
和zookeeper://address21?backup=address22,address23
,同時指定了集群分隔符separator=";"
如下圖所示,不同註冊中心集群的地址將會聚合到一個地址池中,供消費者端進行負載均衡或路由地址選擇。
在 3.1.0 及之後的版本中,也支援在每個註冊中心集群上設定特定的 attachments 屬性,實現對註冊中心集群下地址的特定標記,然後配合 TagRouter 等 Router 組件擴展,實現跨機房流量管理能力。
<dubbo:registry address="multiple://127.0.0.1:2181?separator=;&reference-registry=zookeeper://address11?attachments=zone=hangzhou,tag=middleware;zookeeper://address21" />
添加 attachments=zone=hangzhou,tag=middleware
後,來自該註冊中心的所有 URL 地址都會自動攜帶 zone
和 tag
兩個標識符,方便在消費者端進行更靈活的流量管理。
3 場景範例
3.1 場景 1:跨區域註冊服務
例如:中文網站的某些服務來不及部署在青島,只部署在杭州,而青島的其他應用需要引用此服務,則可以將服務同時註冊到兩個註冊中心。
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" default="false" />
<!-- Register with multiple registries -->
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="hangzhouRegistry,qingdaoRegistry" />
3.2 場景 2:基於業務的隔離
某些 CRM 服務專門為國際網站設計,某些服務專門為中文網站設計。
<!-- Multi-registry configuration -->
<dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
<!-- Register with the Chinese Station Registration Center -->
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="chinaRegistry" />
<!-- Register with the International Station Registration Center -->
<dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" registry="intlRegistry" />
3.3 場景 3:基於業務的服務調用
CRM 需要同時調用中文站和國際站的 PC2 服務,PC2 既部署在中文站也部署在國際站,介面和版本號相同,但連接的資料庫不同。
<!-- Multi-registry configuration -->
<dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
<!-- Quote Chinese station service -->
<dubbo:reference id="chinaHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="chinaRegistry" />
<!-- Reference international station service -->
<dubbo:reference id="intlHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="intlRegistry" />
如果只是測試環境暫時需要連接到兩個不同的註冊中心,使用垂直符號分隔多個不同的註冊中心地址
<!-- Multi-registry configuration, separated by a vertical sign means connecting to multiple different registries at the same time, and multiple cluster addresses of the same registrant are separated by commas -->
<dubbo:registry address="10.20.141.150:9090|10.20.154.177:9010" />
<!-- Reference service -->
<dubbo:reference id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" />