目錄
dubbo 拓展機制 SPI
dubbo 自適應(yīng)拓展機制
dubbo 服務(wù)導(dǎo)出
dubbo 服務(wù)引用
dubbo 服務(wù)字典
dubbo 服務(wù)路由
dubbo 集群
dubbo 負(fù)載均衡
dubbo 服務(wù)調(diào)用過程
官網(wǎng)服務(wù)字典的介紹
本章將分析 AbstractDirectory 和它兩個子類的源碼。AbstractDirectory 封裝了 Invoker 列舉流程试吁,具體的列舉邏輯則由子類實現(xiàn)果港,這是典型的模板模式。而invoker的列舉將會在服務(wù)調(diào)用過程中用到。
接著看AbstractDirectory的list方法贩疙,直接調(diào)用的子類的實現(xiàn)
public List<Invoker<T>> list(Invocation invocation) throws RpcException {
if (destroyed) {
throw new RpcException("Directory already destroyed .url: " + getUrl());
}
return doList(invocation);
}
1.StaticDirectory
StaticDirectory 即靜態(tài)服務(wù)目錄媳溺,顧名思義,它內(nèi)部存放的 Invoker 是不會變動的雪隧。所以西轩,理論上它和不可變 List 的功能很相似。
protected List<Invoker<T>> doList(Invocation invocation) throws RpcException {
List<Invoker<T>> finalInvokers = invokers;
// 進(jìn)行服務(wù)路由
if (routerChain != null) {
try {
finalInvokers = routerChain.route(getConsumerUrl(), invocation);
} catch (Throwable t) {
logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
}
}
return finalInvokers == null ? Collections.emptyList() : finalInvokers;
}
StaticDirectory很簡單脑沿,直接返回的invoker數(shù)組藕畔,沒有過多的操作,接下來看RegistryDirectory會比較復(fù)雜
2. RegistryDirectory
RegistryDirectory 是一種動態(tài)服務(wù)目錄捅伤,實現(xiàn)了 NotifyListener 接口劫流。當(dāng)注冊中心服務(wù)配置發(fā)生變化后,RegistryDirectory 可收到與當(dāng)前服務(wù)相關(guān)的變化丛忆。收到變更通知后祠汇,RegistryDirectory 可根據(jù)配置變更信息刷新 Invoker 列表。RegistryDirectory 中有幾個比較重要的邏輯熄诡,第一是 Invoker 的列舉邏輯可很,第二是接收服務(wù)配置變更的邏輯,第三是 Invoker 列表的刷新邏輯凰浮。接下來按順序?qū)@三塊邏輯進(jìn)行分析
2.1列舉 Invoker
public List<Invoker<T>> doList(Invocation invocation) {
// 服務(wù)提供者關(guān)閉或禁用了服務(wù)我抠,此時拋出 No provider 異常
if (forbidden) {
// 1. No service provider 2. Service providers are disabled
throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, "No provider available from registry " +
getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " +
NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() +
", please check status of providers(disabled, not registered or in blacklist).");
}
// 判斷是否是分組聚合,
if (multiGroup) {
return this.invokers == null ? Collections.emptyList() : this.invokers;
}
List<Invoker<T>> invokers = null;
try {
// Get invokers from cache, only runtime routers will be executed.
invokers = routerChain.route(getConsumerUrl(), invocation);
} catch (Throwable t) {
logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
}
return invokers == null ? Collections.emptyList() : invokers;
}
2.2接收服務(wù)變更通知
RegistryDirectory 是一個動態(tài)服務(wù)目錄袜茧,會隨注冊中心配置的變化進(jìn)行動態(tài)調(diào)整菜拓。因此 RegistryDirectory 實現(xiàn)了 NotifyListener 接口,通過這個接口獲取注冊中心變更通知笛厦。它的notify方法已經(jīng)在上文中的服務(wù)引入過程提到了纳鼎。