以下是一個 Dubbo 屬性設定的例子 dubbo-spring-boot-samples
## application.properties
# Spring boot application
spring.application.name=dubbo-externalized-configuration-provider-sample
# Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service
dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service
# Dubbo Application
## The default value of dubbo.application.name is ${spring.application.name}
## dubbo.application.name=${spring.application.name}
# Dubbo Protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=12345
## Dubbo Registry
dubbo.registry.address=N/A
## service default version
dubbo.provider.version=1.0.0
接下來,我們就圍繞這個範例,分別從設定格式、設定來源、載入流程三個方面對 Dubbo 設定的工作原理進行分析。
目前Dubbo支援的所有設定都是.properties
格式的,包括-D
、Externalized Configuration
等,.properties
中的所有設定項遵循一種path-based
的設定格式。
在Spring應用中也可以將屬性設定放到application.yml
中,其樹層次結構的方式可讀性更好一些。
# 應用級設定(無id)
dubbo.{config-type}.{config-item}={config-item-value}
# 範例級設定(指定id或name)
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
# 服務介面設定
dubbo.service.{interface-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{config-item}={config-item-value}
# 方法設定
dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
# 方法argument設定
dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}
應用級設定的格式為:設定型別單數字首,無id/name。
# 應用級設定(無id)
dubbo.{config-type}.{config-item}={config-item-value}
類似 application
、monitor
、metrics
等都屬於應用級別元件,因此僅允許設定單個範例;而 protocol
、registry
等允許設定多個的元件,在僅需要進行單例設定時,可採用此節描述的格式。常見範例如下:
dubbo.application.name=demo-provider
dubbo.application.qos-enable=false
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
針對某個範例的屬性設定需要指定id或者name,其字首格式為:設定型別複數字首 + id/name。適用於 protocol
、registry
等支援多例設定的元件。
# 範例級設定(指定id或name)
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
設定範例:
dubbo.registries.unit1.address=zookeeper://127.0.0.1:2181
dubbo.registries.unit2.address=zookeeper://127.0.0.1:2182
dubbo.protocols.dubbo.name=dubbo
dubbo.protocols.dubbo.port=20880
dubbo.protocols.hessian.name=hessian
dubbo.protocols.hessian.port=8089
dubbo.service.org.apache.dubbo.samples.api.DemoService.timeout=5000
dubbo.reference.org.apache.dubbo.samples.api.DemoService.timeout=6000
方法設定格式:
# 方法設定
dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
# 方法argument設定
dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}
方法設定範例:
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.timeout=7000
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.oninvoke=notifyService.onInvoke
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.onreturn=notifyService.onReturn
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.onthrow=notifyService.onThrow
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.0.callback=true
等價於XML設定:
<dubbo:reference interface="org.apache.dubbo.samples.api.DemoService" >
<dubbo:method name="sayHello" timeout="7000" oninvoke="notifyService.onInvoke"
onreturn="notifyService.onReturn" onthrow="notifyService.onThrow">
<dubbo:argument index="0" callback="true" />
</dubbo:method>
</dubbo:reference>
parameters引數為map物件,支援xxx.parameters=[{key:value},{key:value}]方式進行設定。
dubbo.application.parameters=[{item1:value1},{item2:value2}]
dubbo.reference.org.apache.dubbo.samples.api.DemoService.parameters=[{item3:value3}]
triple協定採用Http2做底層通訊協定,允許使用者自定義Http2的6個settings引數
設定格式如下:
# 通知對端header壓縮索引表的上限個數
dubbo.rpc.tri.header-table-size=4096
# 啟用伺服器端推播功能
dubbo.rpc.tri.enable-push=false
# 通知對端允許的最大並行流數
dubbo.rpc.tri.max-concurrent-streams=2147483647
# 宣告傳送端的視窗大小
dubbo.rpc.tri.initial-window-size=1048576
# 設定幀的最大位元組數
dubbo.rpc.tri.max-frame-size=32768
# 通知對端header未壓縮的最大位元組數
dubbo.rpc.tri.max-header-list-size=8192
等價於yml設定:
dubbo:
rpc:
tri:
header-table-size: 4096
enable-push: false
max-concurrent-streams: 2147483647
initial-window-size: 1048576
max-frame-size: 32768
max-header-list-size: 8192
可以將 xml 的 tag 名和屬性名組合起來,用 ‘.’ 分隔。每行一個屬性。
dubbo.application.name=foo
相當於 <dubbo:application name="foo" />
dubbo.registry.address=10.20.153.10:9090
相當於 <dubbo:registry address="10.20.153.10:9090" />
如果在 xml 設定中有超過一個的 tag,那麼你可以使用 ‘id’ 進行區分。如果你不指定id,它將作用於所有 tag。
dubbo.protocols.rmi.port=1099
相當於 <dubbo:protocol id="rmi" name="rmi" port="1099" />
dubbo.registries.china.address=10.20.153.10:9090
相當於 <dubbo:registry id="china" address="10.20.153.10:9090" />
複數設定的命名與普通單詞變複數的規則相同:
Config Type | 單數設定 | 複數設定 |
---|---|---|
application | dubbo.application.xxx=xxx | dubbo.applications.{id}.xxx=xxx dubbo.applications.{name}.xxx=xxx |
protocol | dubbo.protocol.xxx=xxx | dubbo.protocols.{id}.xxx=xxx dubbo.protocols.{name}.xxx=xxx |
module | dubbo.module.xxx=xxx | dubbo.modules.{id}.xxx=xxx dubbo.modules.{name}.xxx=xxx |
registry | dubbo.registry.xxx=xxx | dubbo.registries.{id}.xxx=xxx |
monitor | dubbo.monitor.xxx=xxx | dubbo.monitors.{id}.xxx=xxx |
config-center | dubbo.config-center.xxx=xxx | dubbo.config-centers.{id}.xxx=xxx |
metadata-report | dubbo.metadata-report.xxx=xxx | dubbo.metadata-reports.{id}.xxx=xxx |
ssl | dubbo.ssl.xxx=xxx | dubbo.ssls.{id}.xxx=xxx |
metrics | dubbo.metrics.xxx=xxx | dubbo.metricses.{id}.xxx=xxx |
provider | dubbo.provider.xxx=xxx | dubbo.providers.{id}.xxx=xxx |
consumer | dubbo.consumer.xxx=xxx | dubbo.consumers.{id}.xxx=xxx |
service | dubbo.service.{interfaceName}.xxx=xxx | 無 |
reference | dubbo.reference.{interfaceName}.xxx=xxx | 無 |
method | dubbo.service.{interfaceName}.{methodName}.xxx=xxx dubbo.reference.{interfaceName}.{methodName}.xxx=xxx |
無 |
argument | dubbo.service.{interfaceName}.{methodName}.{arg-index}.xxx=xxx | 無 |
Dubbo 預設支援 6 種設定來源:
關於dubbo.properties屬性:
-Ddubbo.properties.file=xxx.properties
。如果通過多種設定來源指定了相同的設定項,則會出現設定項的互相覆蓋,具體覆蓋關係和優先順序請參考下一小節。
Dubbo 設定載入大概分為兩個階段:
發生屬性覆蓋可能有兩種情況,並且二者可能是會同時發生的:
屬性覆蓋是指用設定的屬性值覆蓋config bean範例的屬性,類似Spring PropertyOverrideConfigurer 的作用。
Property resource configurer that overrides bean property values in an application context definition. It pushes values from a properties file into bean definitions.
Configuration lines are expected to be of the following form:beanName.property=value
但與PropertyOverrideConfigurer
的不同之處是,Dubbo的屬性覆蓋有多個匹配格式,優先順序從高到低依次是:
#1. 指定id的範例級設定
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
#2. 指定name的範例級設定
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
#3. 應用級設定(單數設定)
dubbo.{config-type}.{config-item}={config-item-value}
屬性覆蓋處理流程:
按照優先順序從高到低依次查詢,如果找到此字首開頭的屬性,則選定使用這個字首提取屬性,忽略後面的設定。
外部化設定目的之一是實現設定的集中式管理,這部分業界已經有很多成熟的專業設定系統如 Apollo, Nacos 等,Dubbo 所做的主要是保證能配合這些系統正常工作。
外部化設定和其他本地設定在內容和格式上並無區別,可以簡單理解為 dubbo.properties
的外部化儲存,設定中心更適合將一些公共設定如註冊中心、後設資料中心設定等抽取以便做集中管理。
# 將註冊中心地址、後設資料中心地址等設定集中管理,可以做到統一環境、減少開發側感知。
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.registry.simplified=true
dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.application.qos.port=33333
優先順序
外部化設定預設較本地設定有更高的優先順序,因此這裡設定的內容會覆蓋本地設定值,關於各設定形式間的覆蓋關係 有單獨一章說明。
作用域
外部化設定有全域性和應用兩個級別,全域性設定是所有應用共用的,應用級設定是由每個應用自己維護且只對自身可見的。當前已支援的擴充套件實現有 Zookeeper、Apollo、Nacos。
<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
開啟外部化設定後,registry、metadata-report、protocol、qos 等全域性範圍的設定理論上都不再需要在應用中設定,應用開發側專注業務服務設定,一些全域性共用的全域性設定轉而由運維人員統一設定在遠端設定中心。
這樣能做到的效果就是,應用只需要關心:
舉例來說,每個應用中 Dubbo 相關的設定只有以下內容可能就足夠了,其餘的都託管給相應環境下的設定中心:
dubbo
application
name: demo
config-center
address: nacos://127.0.0.1:8848
所謂 Dubbo 對設定中心的支援,本質上就是把 .properties
從遠端拉取到本地,然後和原生的設定做一次融合。理論上只要 Dubbo 框架能拿到需要的設定就可以正常的啟動,它並不關心這些設定是自己載入到的還是應用直接塞給它的,所以Dubbo還提供了以下API,讓使用者將自己組織好的設定塞給 Dubbo 框架(設定載入的過程是使用者要完成的),這樣 Dubbo 框架就不再直接和 Apollo 或 Zookeeper 做讀取設定互動。
// 應用自行載入設定
Map<String, String> dubboConfigurations = new HashMap<>();
dubboConfigurations.put("dubbo.registry.address", "zookeeper://127.0.0.1:2181");
dubboConfigurations.put("dubbo.registry.simplified", "true");
//將組織好的設定塞給Dubbo框架
ConfigCenterConfig configCenter = new ConfigCenterConfig();
configCenter.setExternalConfig(dubboConfigurations);
歡迎在 https://github.com/apache/dubbo 給 Dubbo Star。
搜尋關注官方微信公眾號:Apache Dubbo,瞭解更多業界最新動態,掌握大廠面試必備 Dubbo 技能