(#)html
隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已沒法應對,分佈式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。前端
(#)java
在大規模服務化以前,應用可能只是經過RMI或Hessian等工具,簡單的暴露和引用遠程服務,經過配置服務的URL地址進行調用,經過F5等硬件進行負載均衡。node
(1) 當服務愈來愈多時,服務URL配置管理變得很是困難,F5硬件負載均衡器的單點壓力也愈來愈大。linux
此時須要一個服務註冊中心,動態的註冊和發現服務,使服務的位置透明。git
並經過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,下降對F5硬件負載均衡器的依賴,也能減小部分紅本。github
(2) 當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪一個應用要在哪一個應用以前啓動,架構師都不能完整的描述應用的架構關係。web
這時,須要自動畫出應用間的依賴關係圖,以幫助架構師理清理關係。redis
(3) 接着,服務的調用量愈來愈大,服務的容量問題就暴露出來,這個服務須要多少機器支撐?何時該加機器?
爲了解決這些問題,第一步,要將服務如今天天的調用量,響應時間,都統計出來,做爲容量規劃的參考指標。
其次,要能夠動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程當中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。
以上是Dubbo最基本的幾個需求,更多服務治理問題參見:
http://code.alibabatech.com/blog/experience_1402/service-governance-process.html
(#)
節點角色說明:
調用關係說明:
(1) 連通性:
(2) 健狀性:
(3) 伸縮性:
(4) 升級性:
(#)
<
bean
id=「xxxService」 class=「com.xxx.XxxServiceImpl」 />
<
bean
id=「xxxAction」 class=「com.xxx.XxxAction」>
<
property
name=「xxxService」 ref=「xxxService」 />
</
bean
>
|
在本地服務的基礎上,只需作簡單配置,便可完成遠程化:
以下:
<
bean
id=「xxxService」 class=「com.xxx.XxxServiceImpl」 />
<!-- 和本地服務同樣實現遠程服務 -->
<
dubbo:service
interface=「com.xxx.XxxService」 ref=「xxxService」 />
<!-- 增長暴露遠程服務配置 -->
|
<
dubbo:reference
id=「xxxService」 interface=「com.xxx.XxxService」 />
<!-- 增長引用遠程服務配置 -->
<
bean
id=「xxxAction」 class=「com.xxx.XxxAction」>
<!-- 和本地服務同樣使用遠程服務 -->
<
property
name=「xxxService」 ref=「xxxService」 />
</
bean
>
|
Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring加載Dubbo的配置便可,Dubbo基於Spring的Schema擴展進行加載。 |
(#)
定義服務接口: (該接口需單獨打包,在服務提供方和消費方共享)
package
com.alibaba.dubbo.demo;
public
interface
DemoService {
String sayHello(String name);
}
|
在服務提供方實現接口:(對服務消費方隱藏實現)
package
com.alibaba.dubbo.demo.provider;
import
com.alibaba.dubbo.demo.DemoService;
public
class
DemoServiceImpl
implements
DemoService {
public
String sayHello(String name) {
return
"Hello "
+ name;
}
}
|
用Spring配置聲明暴露服務:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<!-- 提供方應用信息,用於計算依賴關係 -->
<
dubbo:application
name
=
"hello-world-app"
/>
<!-- 使用multicast廣播註冊中心暴露服務地址 -->
<
dubbo:registry
address
=
"multicast://224.5.6.7:1234"
/>
<!-- 用dubbo協議在20880端口暴露服務 -->
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
/>
<!-- 聲明須要暴露的服務接口 -->
<
dubbo:service
interface
=
"com.alibaba.dubbo.demo.DemoService"
ref
=
"demoService"
/>
<!-- 和本地bean同樣實現服務 -->
<
bean
id
=
"demoService"
class
=
"com.alibaba.dubbo.demo.provider.DemoServiceImpl"
/>
</
beans
>
|
加載Spring配置:
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public
class
Provider {
public
static
void
main(String[] args)
throws
Exception {
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(
new
String[] {
"http://10.20.160.198/wiki/display/dubbo/provider.xml"
});
context.start();
System.in.read();
// 按任意鍵退出
}
}
|
(#)
經過Spring配置引用遠程服務:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方同樣 -->
<
dubbo:application
name
=
"consumer-of-helloworld-app"
/>
<!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
<
dubbo:registry
address
=
"multicast://224.5.6.7:1234"
/>
<!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService -->
<
dubbo:reference
id
=
"demoService"
interface
=
"com.alibaba.dubbo.demo.DemoService"
/>
</
beans
>
|
加載Spring配置,並調用遠程服務:(也能夠使用IoC注入)
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import
com.alibaba.dubbo.demo.DemoService;
public
class
Consumer {
public
static
void
main(String[] args)
throws
Exception {
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(
new
String[] {
"http://10.20.160.198/wiki/display/dubbo/consumer.xml"
});
context.start();
DemoService demoService = (DemoService)context.getBean(
"demoService"
);
// 獲取遠程服務代理
String hello = demoService.sayHello(
"world"
);
// 執行遠程方法
System.out.println( hello );
// 顯示調用結果
}
}
|
理論上Dubbo能夠只依賴JDK,不依賴於任何三方庫運行,只需配置使用JDK相關實現策略。 |
經過mvn dependency:tree > dep.log命令分析,Dubbo缺省依賴如下三方庫:
[INFO] +- com.alibaba:dubbo:jar:2.1.2:compile
[INFO] | +- log4j:log4j:jar:1.2.16:compile
[INFO] | +- org.javassist:javassist:jar:3.15.0-GA:compile
[INFO] | +- org.springframework:spring:jar:2.5.6.SEC03:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] | \- org.jboss.netty:netty:jar:3.2.5.Final:compile
|
這裏全部依賴都是換照Dubbo缺省配置選的,這些缺省值是基於穩定性和性能考慮的。
如下依賴,在主動配置使用相應實現策略時用到,需自行加入依賴。
JEE:
(#)
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
併發控制 | Tested | 併發控制 | 試用 | ||
鏈接控制 | Tested | 鏈接數控制 | 試用 | ||
直連提供者 | Tested | 點對點直連服務提供方,用於測試 | 測試環境使用 | Alibaba | |
分組聚合 | Tested | 分組聚合返回值,用於菜單聚合等服務 | 特殊場景使用 | 可用於生產環境 | |
參數驗證 | Tested | 參數驗證,JSR303驗證框架集成 | 對性能有影響 | 試用 | LaiWang |
結果緩存 | Tested | 結果緩存,用於加速請求 | 試用 | ||
泛化引用 | Stable | 泛化調用,無需業務接口類進行遠程調用,用於測試平臺,開放網關橋接等 | 可用於生產環境 | Alibaba | |
泛化實現 | Stable | 泛化實現,無需業務接口類實現任意接口,用於Mock平臺 | 可用於生產環境 | Alibaba | |
回聲測試 | Tested | 回聲測試 | 試用 | ||
隱式傳參 | Stable | 附加參數 | 可用於生產環境 | ||
異步調用 | Tested | 不可靠異步調用 | 試用 | ||
本地調用 | Tested | 本地調用 | 試用 | ||
參數回調 | Tested | 參數回調 | 特殊場景使用 | 試用 | Registry |
事件通知 | Tested | 事件通知,在遠程調用執行先後觸發 | 試用 | ||
本地存根 | Stable | 在客戶端執行部分邏輯 | 可用於生產環境 | Alibaba | |
本地假裝 | Stable | 僞造返回結果,可在失敗時執行,或直接執行,用於服務降級 | 需註冊中心支持 | 可用於生產環境 | Alibaba |
延遲暴露 | Stable | 延遲暴露服務,用於等待應用加載warmup數據,或等待spring加載完成 | 可用於生產環境 | Alibaba | |
延遲鏈接 | Tested | 延遲創建鏈接,調用時創建 | 試用 | Registry | |
粘滯鏈接 | Tested | 粘滯鏈接,老是向同一個提供方發起請求,除非此提供方掛掉,再切換到另外一臺 | 試用 | Registry | |
令牌驗證 | Tested | 令牌驗證,用於服務受權 | 需註冊中心支持 | 試用 | |
路由規則 | Tested | 動態決定調用關係 | 需註冊中心支持 | 試用 | |
配置規則 | Tested | 動態下發配置,實現功能的開關 | 需註冊中心支持 | 試用 | |
訪問日誌 | Tested | 訪問日誌,用於記錄調用信息 | 本地存儲,影響性能,受磁盤大小限制 | 試用 | |
分佈式事務 | Research | JTA/XA三階段提交事務 | 不穩定 | 不可用 |
(#)
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Zookeeper註冊中心 | Stable | 支持基於網絡的集羣方式,有普遍周邊開源產品,建議使用dubbo-2.3.3以上版本(推薦使用) | 依賴於Zookeeper的穩定性 | 可用於生產環境 | |
Redis註冊中心 | Stable | 支持基於客戶端雙寫的集羣方式,性能高 | 要求服務器時間同步,用於檢查心跳過時髒數據 | 可用於生產環境 | |
Multicast註冊中心 | Tested | 去中心化,不須要安裝註冊中心 | 依賴於網絡拓普和路由,跨機房有風險 | 小規模應用或開發測試環境 | |
Simple註冊中心 | Tested | Dogfooding,註冊中心自己也是一個標準的RPC服務 | 沒有集羣支持,可能單點故障 | 試用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Simple監控中心 | Stable | 支持JFreeChart統計報表 | 沒有集羣支持,可能單點故障,但故障後不影響RPC運行 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Dubbo協議 | Stable | 採用NIO複用單一長鏈接,並使用線程池併發處理請求,減小握手和加大併發效率,性能較好(推薦使用) | 在大文件傳輸時,單一鏈接會成爲瓶頸 | 可用於生產環境 | Alibaba |
Rmi協議 | Stable | 可與原生RMI互操做,基於TCP協議 | 偶爾會鏈接失敗,需重建Stub | 可用於生產環境 | Alibaba |
Hessian協議 | Stable | 可與原生Hessian互操做,基於HTTP協議 | 需hessian.jar支持,http短鏈接的開銷大 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Netty Transporter | Stable | JBoss的NIO框架,性能較好(推薦使用) | 一次請求派發兩種事件,需屏蔽無用事件 | 可用於生產環境 | Alibaba |
Mina Transporter | Stable | 老牌NIO框架,穩定 | 待發送消息隊列派發不及時,大壓力下,會出現FullGC | 可用於生產環境 | Alibaba |
Grizzly Transporter | Tested | Sun的NIO框架,應用於GlassFish服務器中 | 線程池不可擴展,Filter不能攔截下一Filter | 試用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Hessian Serialization | Stable | 性能較好,多語言支持(推薦使用) | Hessian的各版本兼容性很差,可能和應用使用的Hessian衝突,Dubbo內嵌了hessian3.2.1的源碼 | 可用於生產環境 | Alibaba |
Dubbo Serialization | Tested | 經過不傳送POJO的類元信息,在大量POJO傳輸時,性能較好 | 當參數對象增長字段時,需外部文件聲明 | 試用 | |
Json Serialization | Tested | 純文本,可跨語言解析,缺省採用FastJson解析 | 性能較差 | 試用 | |
Java Serialization | Stable | Java原生支持 | 性能較差 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Javassist ProxyFactory | Stable | 經過字節碼生成代替反射,性能比較好(推薦使用) | 依賴於javassist.jar包,佔用JVM的Perm內存,Perm可能要設大一些:java -XX:PermSize=128m | 可用於生產環境 | Alibaba |
Jdk ProxyFactory | Stable | JDK原生支持 | 性能較差 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Failover Cluster | Stable | 失敗自動切換,當出現失敗,重試其它服務器,一般用於讀操做(推薦使用) | 重試會帶來更長延遲 | 可用於生產環境 | Alibaba |
Failfast Cluster | Stable | 快速失敗,只發起一次調用,失敗當即報錯,一般用於非冪等性的寫操做 | 若是有機器正在重啓,可能會出現調用失敗 | 可用於生產環境 | Alibaba |
Failsafe Cluster | Stable | 失敗安全,出現異常時,直接忽略,一般用於寫入審計日誌等操做 | 調用信息丟失 | 可用於生產環境 | Monitor |
Failback Cluster | Tested | 失敗自動恢復,後臺記錄失敗請求,定時重發,一般用於消息通知操做 | 不可靠,重啓丟失 | 可用於生產環境 | Registry |
Forking Cluster | Tested | 並行調用多個服務器,只要一個成功即返回,一般用於實時性要求較高的讀操做 | 須要浪費更多服務資源 | 可用於生產環境 | |
Broadcast Cluster | Tested | 廣播調用全部提供者,逐個調用,任意一臺報錯則報錯,一般用於更新提供方本地狀態 | 速度慢,任意一臺報錯則報錯 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Random LoadBalance | Stable | 隨機,按權重設置隨機機率(推薦使用) | 在一個截面上碰撞的機率高,重試時,可能出現瞬間壓力不均 | 可用於生產環境 | Alibaba |
RoundRobin LoadBalance | Stable | 輪循,按公約後的權重設置輪循比率 | 存在慢的機器累積請求問題,極端狀況可能產生雪崩 | 可用於生產環境 | |
LeastActive LoadBalance | Stable | 最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差,使慢的機器收到更少請求 | 不支持權重,在容量規劃時,不能經過權重把壓力導向一臺機器壓測容量 | 可用於生產環境 | |
ConsistentHash LoadBalance | Stable | 一致性Hash,相同參數的請求老是發到同一提供者,當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更 | 壓力分攤不均 | 可用於生產環境 | |
Feature | Maturity | Strength | Problem | Advise | User |
條件路由規則 | Stable | 基於條件表達式的路由規則,功能簡單易用 | 有些複雜多分支條件狀況,規則很難描述 | 可用於生產環境 | Alibaba |
腳本路由規則 | Tested | 基於腳本引擎的路由規則,功能強大 | 沒有運行沙箱,腳本能力過於強大,可能成爲後門 | 試用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Spring Container | Stable | 自動加載META-INF/spring目錄下的全部Spring配置 | 可用於生產環境 | Alibaba | |
Jetty Container | Stable | 啓動一個內嵌Jetty,用於彙報狀態 | 大量訪問頁面時,會影響服務器的線程和內存 | 可用於生產環境 | Alibaba |
Log4j Container | Stable | 自動配置log4j的配置,在多進程啓動時,自動給日誌文件按進程分目錄 | 用戶不能控制log4j的配置,不靈活 | 可用於生產環境 | Alibaba |
示例:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"hello-world-app"
/>
<
dubbo:registry
address
=
"multicast://224.5.6.7:1234"
/>
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
/>
<
dubbo:service
interface
=
"com.alibaba.dubbo.demo.DemoService"
ref
=
"demoServiceLocal"
/>
<
dubbo:reference
id
=
"demoServiceRemote"
interface
=
"com.alibaba.dubbo.demo.DemoService"
/>
</
beans
>
|
全部標籤者支持自定義參數,用於不一樣擴展點實現的特殊配置。 |
如:
<
dubbo:protocol
name
=
"jms"
>
</
dubbo:protocol
>
|
或:(2.1.0開始支持)
注意聲明:xmlns:p="http://www.springframework.org/schema/p" |
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
</
beans
>
|
Configuration Relation:
Configuration Override:
若是公共配置很簡單,沒有多註冊中心,多協議等狀況,或者想多個Spring容器想共享配置,能夠使用dubbo.properties做爲缺省配置。 |
Dubbo將自動加載classpath根目錄下的dubbo.properties,能夠經過JVM啓動參數:-Ddubbo.properties.file=xxx.properties 改變缺省配置位置。 |
若是classpath根目錄下存在多個dubbo.properties,好比多個jar包中有dubbo.properties,Dubbo會任意加載,並打印Error日誌,後續可能改成拋異常。 |
映射規則:
典型配置如:
dubbo.application.name=foo
dubbo.application.owner=bar
dubbo.registry.address=
10.20
.
153.10
:
9090
|
覆蓋策略:
2.2.1以上版本支持 |
服務提供方註解:
import
com.alibaba.dubbo.config.annotation.Service;
@Service
(version=
"1.0.0"
)
public
class
FooServiceImpl
implements
FooService {
// ......
}
|
服務提供方配置:
<!-- 公共信息,也能夠用dubbo.properties配置 -->
<
dubbo:application
name
=
"annotation-provider"
/>
<
dubbo:registry
address
=
"127.0.0.1:4548"
/>
<!-- 掃描註解包路徑,多個包用逗號分隔,不填pacakge表示掃描當前ApplicationContext中全部的類 -->
<
dubbo:annotation
package
=
"com.foo.bar.service"
/>
|
服務消費方註解:
import
com.alibaba.dubbo.config.annotation.Reference;
import
org.springframework.stereotype.Component;
@Component
public
class
BarAction {
@Reference
(version=
"1.0.0"
)
private
FooService fooService;
}
|
服務消費方配置:
<!-- 公共信息,也能夠用dubbo.properties配置 -->
<
dubbo:application
name
=
"annotation-consumer"
/>
<
dubbo:registry
address
=
"127.0.0.1:4548"
/>
<!-- 掃描註解包路徑,多個包用逗號分隔,不填pacakge表示掃描當前ApplicationContext中全部的類 -->
<
dubbo:annotation
package
=
"com.foo.bar.action"
/>
|
也能夠使用:(等價於前面的:<dubbo:annotation package="com.foo.bar.service" />)
<
dubbo:annotation
/>
<
context:component-scan
base-package
=
"com.foo.bar.service"
>
<
context:include-filter
type
=
"annotation"
expression
=
"com.alibaba.dubbo.config.annotation.Service"
/>
</
context:component-scan
>
|
Spring2.5及之後版本支持component-scan,若是用的是Spring2.0及之前版本,需配置:
|
API屬性含義參考 API屬性與配置項一對一,各屬性含義,請參見:配置參考手冊 (+), 好比:ApplicationConfig.setName("xxx") 對應 <dubbo:application name="xxx" /> |
import
com.alibaba.dubbo.rpc.config.ApplicationConfig;
import
com.alibaba.dubbo.rpc.config.RegistryConfig;
import
com.alibaba.dubbo.rpc.config.ProviderConfig;
import
com.alibaba.dubbo.rpc.config.ServiceConfig;
import
com.xxx.XxxService;
import
com.xxx.XxxServiceImpl;
// 服務實現
XxxService xxxService =
new
XxxServiceImpl();
// 當前應用配置
ApplicationConfig application =
new
ApplicationConfig();
application.setName(
"xxx"
);
// 鏈接註冊中心配置
RegistryConfig registry =
new
RegistryConfig();
registry.setAddress(
"10.20.130.230:9090"
);
registry.setUsername(
"aaa"
);
registry.setPassword(
"bbb"
);
// 服務提供者協議配置
ProtocolConfig protocol =
new
ProtocolConfig();
protocol.setName(
"dubbo"
);
protocol.setPort(
12345
);
protocol.setThreads(
200
);
// 注意:ServiceConfig爲重對象,內部封裝了與註冊中心的鏈接,以及開啓服務端口
// 服務提供者暴露服務配置
ServiceConfig<XxxService> service =
new
ServiceConfig<XxxService>();
// 此實例很重,封裝了與註冊中心的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
service.setApplication(application);
service.setRegistry(registry);
// 多個註冊中心能夠用setRegistries()
service.setProtocol(protocol);
// 多個協議能夠用setProtocols()
service.setInterface(XxxService.
class
);
service.setRef(xxxService);
service.setVersion(
"1.0.0"
);
// 暴露及註冊服務
service.export();
|
import
com.alibaba.dubbo.rpc.config.ApplicationConfig;
import
com.alibaba.dubbo.rpc.config.RegistryConfig;
import
com.alibaba.dubbo.rpc.config.ConsumerConfig;
import
com.alibaba.dubbo.rpc.config.ReferenceConfig;
import
com.xxx.XxxService;
// 當前應用配置
ApplicationConfig application =
new
ApplicationConfig();
application.setName(
"yyy"
);
// 鏈接註冊中心配置
RegistryConfig registry =
new
RegistryConfig();
registry.setAddress(
"10.20.130.230:9090"
);
registry.setUsername(
"aaa"
);
registry.setPassword(
"bbb"
);
// 注意:ReferenceConfig爲重對象,內部封裝了與註冊中心的鏈接,以及與服務提供方的鏈接
// 引用遠程服務
ReferenceConfig<XxxService> reference =
new
ReferenceConfig<XxxService>();
// 此實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
reference.setApplication(application);
reference.setRegistry(registry);
// 多個註冊中心能夠用setRegistries()
reference.setInterface(XxxService.
class
);
reference.setVersion(
"1.0.0"
);
// 和本地bean同樣使用xxxService
XxxService xxxService = reference.get();
// 注意:此代理對象內部封裝了全部通信細節,對象較重,請緩存複用
|
注:下面只列出不一樣的地方,其它參見上面的寫法
...
// 方法級配置
List<MethodConfig> methods =
new
ArrayList<MethodConfig>();
MethodConfig method =
new
MethodConfig();
method.setName(
"createXxx"
);
method.setTimeout(
10000
);
method.setRetries(
0
);
methods.add(method);
// 引用遠程服務
ReferenceConfig<XxxService> reference =
new
ReferenceConfig<XxxService>();
// 此實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
...
reference.setMethods(methods);
// 設置方法級配置
...
|
...
ReferenceConfig<XxxService> reference =
new
ReferenceConfig<XxxService>();
// 此實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
// 若是點對點直連,能夠用reference.setUrl()指定目標地址,設置url後將繞過註冊中心,
// 其中,協議對應provider.setProtocol()的值,端口對應provider.setPort()的值,
// 路徑對應service.setPath()的值,若是未設置path,缺省path爲接口名
reference.setUrl(
"dubbo://10.20.130.230:20880/com.xxx.XxxService"
);
...
|
Dubbo缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止Spring初始化完成,以便上線時,能及早發現問題,默認check=true。 |
若是你的Spring容器是懶加載的,或者經過API編程延遲引用服務,請關閉check,不然服務臨時不可用時,會拋出異常,拿到null引用,若是check=false,老是會返回引用,當服務恢復時,能自動連上。 |
能夠經過check="false"關閉檢查,好比,測試時,有些服務不關心,或者出現了循環依賴,必須有一方先啓動。
關閉某個服務的啓動時檢查:(沒有提供者時報錯)
<
dubbo:reference
interface
=
"com.foo.BarService"
check
=
"false"
/>
|
關閉全部服務的啓動時檢查:(沒有提供者時報錯)
<
dubbo:consumer
check
=
"false"
/>
|
關閉註冊中心啓動時檢查:(註冊訂閱失敗時報錯)
<
dubbo:registry
check
=
"false"
/>
|
也能夠用dubbo.properties配置:
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
|
也能夠用-D參數:
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
|
注意區別
|
引用缺省是延遲初始化的,只有引用被注入到其它Bean,或被getBean()獲取,纔會初始化。
若是須要飢餓加載,即沒有人引用也當即生成動態代理,能夠配置:
<
dubbo:reference
interface
=
"com.foo.BarService"
init
=
"true"
/>
|
在集羣調用失敗時,Dubbo提供了多種容錯方案,缺省爲failover重試。 |
各節點關係:
能夠自行擴展集羣容錯策略,參見:集羣擴展
重試次數配置如:(failover集羣模式生效)
<
dubbo:service
retries
=
"2"
/>
|
或:
<
dubbo:reference
retries
=
"2"
/>
|
或:
<
dubbo:reference
>
<
dubbo:method
name
=
"findFoo"
retries
=
"2"
/>
</
dubbo:reference
>
|
集羣模式配置如:
<
dubbo:service
cluster
=
"failsafe"
/>
|
或:
<
dubbo:reference
cluster
=
"failsafe"
/>
|
在集羣負載均衡時,Dubbo提供了多種均衡策略,缺省爲random隨機調用。 |
能夠自行擴展負載均衡策略,參見:負載均衡擴展
配置如:
<
dubbo:service
interface
=
"..."
loadbalance
=
"roundrobin"
/>
|
或:
<
dubbo:reference
interface
=
"..."
loadbalance
=
"roundrobin"
/>
|
或:
<
dubbo:service
interface
=
"..."
>
<
dubbo:method
name
=
"..."
loadbalance
=
"roundrobin"
/>
</
dubbo:service
>
|
或:
<
dubbo:reference
interface
=
"..."
>
<
dubbo:method
name
=
"..."
loadbalance
=
"roundrobin"
/>
</
dubbo:reference
>
|
事件處理線程說明
|
配置如:
<
dubbo:protocol
name
=
"dubbo"
dispatcher
=
"all"
threadpool
=
"fixed"
threads
=
"100"
/>
|
在開發及測試環境下,常常須要繞過註冊中心,只測試指定服務提供者,這時候可能須要點對點直連,
點對點直聯方式,將以服務接口爲單位,忽略註冊中心的提供者列表,
A接口配置點對點,不影響B接口從註冊中心獲取列表。
(1) 若是是線上需求須要點對點,可在<dubbo:reference>中配置url指向提供者,將繞過註冊中心,多個地址用分號隔開,配置以下:(1.0.6及以上版本支持)
<dubbo:reference id=
"xxxService"
interface
=
"com.alibaba.xxx.XxxService"
url=
"dubbo://localhost:20890"
/>
|
(2) 在JVM啓動參數中加入-D參數映射服務地址,如:
(key爲服務名,value爲服務提供者url,此配置優先級最高,1.0.15及以上版本支持)
java -Dcom.alibaba.xxx.XxxService=dubbo:
//localhost:20890
|
注意 爲了不復雜化線上環境,不要在線上使用這個功能,只應在測試階段使用。 |
(3) 若是服務比較多,也能夠用文件映射,如:
(用-Ddubbo.resolve.file指定映射文件路徑,此配置優先級高於<dubbo:reference>中的配置,1.0.15及以上版本支持)
(2.0以上版本自動加載${user.home}/dubbo-resolve.properties文件,不須要配置)
java -Ddubbo.resolve.file=xxx.properties
|
而後在映射文件xxx.properties中加入:
(key爲服務名,value爲服務提供者url)
com.alibaba.xxx.XxxService=dubbo:
//localhost:20890
|
注意 爲了不復雜化線上環境,不要在線上使用這個功能,只應在測試階段使用。 |
問題 爲方便開發測試,常常會在線下共用一個全部服務可用的註冊中心,這時,若是一個正在開發中的服務提供者註冊,可能會影響消費者不能正常運行。 |
解決方案 可讓服務提供者開發方,只訂閱服務(開發的服務可能依賴其它服務),而不註冊正在開發的服務,經過直連測試正在開發的服務。 |
禁用註冊配置:
<
dubbo:registry
address
=
"10.20.153.10:9090"
register
=
"false"
/>
|
或者:
<
dubbo:registry
address
=
"10.20.153.10:9090?register=false"
/>
|
問題 若是有兩個鏡像環境,兩個註冊中心,有一個服務只在其中一個註冊中心有部署,另外一個註冊中心還沒來得及部署,而兩個註冊中心的其它應用都須要依賴此服務,因此須要將服務同時註冊到兩個註冊中心,但卻不能讓此服務同時依賴兩個註冊中心的其它服務。 |
解決方案 可讓服務提供者方,只註冊服務到另外一註冊中心,而不從另外一註冊中心訂閱服務。 |
禁用訂閱配置:
<
dubbo:registry
id
=
"hzRegistry"
address
=
"10.20.153.10:9090"
/>
<
dubbo:registry
id
=
"qdRegistry"
address
=
"10.20.141.150:9090"
subscribe
=
"false"
/>
|
或者:
<
dubbo:registry
id
=
"hzRegistry"
address
=
"10.20.153.10:9090"
/>
<
dubbo:registry
id
=
"qdRegistry"
address
=
"10.20.141.150:9090?subscribe=false"
/>
|
有時候但願人工管理服務提供者的上線和下線,此時需將註冊中心標識爲非動態管理模式。 |
<
dubbo:registry
address
=
"10.20.141.150:9090"
dynamic
=
"false"
/>
|
或者:
<
dubbo:registry
address
=
"10.20.141.150:9090?dynamic=false"
/>
|
服務提供者初次註冊時爲禁用狀態,需人工啓用,斷線時,將不會被自動刪除,需人工禁用。
若是是一個第三方獨立提供者,好比memcached等,能夠直接向註冊中心寫入提供者地址信息,消費者正常使用:
(一般由腳本監控中心頁面等調用)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"memcached://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo"
));
|
能夠自行擴展協議,參見:協議擴展
好比:不一樣服務在性能上適用不一樣協議進行傳輸,好比大數據用短鏈接協議,小數據大併發用長鏈接協議。
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<
dubbo:registry
id
=
"registry"
address
=
"10.20.141.150:9090"
username
=
"admin"
password
=
"hello1234"
/>
<!-- 多協議配置 -->
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
/>
<
dubbo:protocol
name
=
"rmi"
port
=
"1099"
/>
<!-- 使用dubbo協議暴露服務 -->
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
protocol
=
"dubbo"
/>
<!-- 使用rmi協議暴露服務 -->
<
dubbo:service
interface
=
"com.alibaba.hello.api.DemoService"
version
=
"1.0.0"
ref
=
"demoService"
protocol
=
"rmi"
/>
</
beans
>
|
好比:須要與http客戶端互操做
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<
dubbo:registry
id
=
"registry"
address
=
"10.20.141.150:9090"
username
=
"admin"
password
=
"hello1234"
/>
<!-- 多協議配置 -->
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
/>
<
dubbo:protocol
name
=
"hessian"
port
=
"8080"
/>
<!-- 使用多個協議暴露服務 -->
<
dubbo:service
id
=
"helloService"
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
protocol
=
"dubbo,hessian"
/>
</
beans
>
|
能夠自行擴展註冊中心,參見:註冊中心擴展
好比:中文站有些服務來不及在青島部署,只在杭州部署,而青島的其它應用須要引用此服務,就能夠將服務同時註冊到兩個註冊中心。
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<!-- 多註冊中心配置 -->
<
dubbo:registry
id
=
"hangzhouRegistry"
address
=
"10.20.141.150:9090"
/>
<
dubbo:registry
id
=
"qingdaoRegistry"
address
=
"10.20.141.151:9010"
default
=
"false"
/>
<!-- 向多個註冊中心註冊 -->
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
registry
=
"hangzhouRegistry,qingdaoRegistry"
/>
</
beans
>
|
好比:CRM有些服務是專門爲國際站設計的,有些服務是專門爲中文站設計的。
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<!-- 多註冊中心配置 -->
<
dubbo:registry
id
=
"chinaRegistry"
address
=
"10.20.141.150:9090"
/>
<
dubbo:registry
id
=
"intlRegistry"
address
=
"10.20.154.177:9010"
default
=
"false"
/>
<!-- 向中文站註冊中心註冊 -->
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
registry
=
"chinaRegistry"
/>
<!-- 向國際站註冊中心註冊 -->
<
dubbo:service
interface
=
"com.alibaba.hello.api.DemoService"
version
=
"1.0.0"
ref
=
"demoService"
registry
=
"intlRegistry"
/>
</
beans
>
|
好比:CRM需同時調用中文站和國際站的PC2服務,PC2在中文站和國際站均有部署,接口及版本號都同樣,但連的數據庫不同。
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<!-- 多註冊中心配置 -->
<
dubbo:registry
id
=
"chinaRegistry"
address
=
"10.20.141.150:9090"
/>
<
dubbo:registry
id
=
"intlRegistry"
address
=
"10.20.154.177:9010"
default
=
"false"
/>
<!-- 引用中文站服務 -->
<
dubbo:reference
id
=
"chinaHelloService"
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
registry
=
"chinaRegistry"
/>
<!-- 引用國際站站服務 -->
<
dubbo:reference
id
=
"intlHelloService"
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
registry
=
"intlRegistry"
/>
</
beans
>
|
若是隻是測試環境臨時須要鏈接兩個不一樣註冊中心,使用豎號分隔多個不一樣註冊中心地址:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<
dubbo:application
name
=
"world"
/>
<!-- 多註冊中心配置,豎號分隔表示同時鏈接多個不一樣註冊中心,同一註冊中心的多個集羣地址用逗號分隔 -->
<
dubbo:registry
address
=
"10.20.141.150:9090|10.20.154.177:9010"
/>
<!-- 引用服務 -->
<
dubbo:reference
id
=
"helloService"
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
/>
</
beans
>
|
當一個接口有多種實現時,能夠用group區分。 |
<
dubbo:service
group
=
"feedback"
interface
=
"com.xxx.IndexService"
/>
<
dubbo:service
group
=
"member"
interface
=
"com.xxx.IndexService"
/>
|
<
dubbo:reference
id
=
"feedbackIndexService"
group
=
"feedback"
interface
=
"com.xxx.IndexService"
/>
<
dubbo:reference
id
=
"memberIndexService"
group
=
"member"
interface
=
"com.xxx.IndexService"
/>
|
任意組:(2.2.0以上版本支持,老是隻調一個可用組的實現)
<
dubbo:reference
id
=
"barService"
interface
=
"com.foo.BarService"
group
=
"*"
/>
|
當一個接口實現,出現不兼容升級時,能夠用版本號過渡,版本號不一樣的服務相互間不引用。 |
<
dubbo:service
interface
=
"com.foo.BarService"
version
=
"1.0.0"
/>
|
<
dubbo:service
interface
=
"com.foo.BarService"
version
=
"2.0.0"
/>
|
<
dubbo:reference
id
=
"barService"
interface
=
"com.foo.BarService"
version
=
"1.0.0"
/>
|
<
dubbo:reference
id
=
"barService"
interface
=
"com.foo.BarService"
version
=
"2.0.0"
/>
|
不區分版本:(2.2.0以上版本支持)
<
dubbo:reference
id
=
"barService"
interface
=
"com.foo.BarService"
version
=
"*"
/>
|
按組合並返回結果,好比菜單服務,接口同樣,但有多種實現,用group區分,如今消費方需從每種group中調用一次返回結果,合併結果返回,這樣就能夠實現聚合菜單項。 |
從2.1.0版本開始支持 |
配置如:(搜索全部分組)
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"*"
merger
=
"true"
/>
|
或:(合併指定分組)
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"aaa,bbb"
merger
=
"true"
/>
|
或:(指定方法合併結果,其它未指定的方法,將只調用一個Group)
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"*"
>
<
dubbo:method
name
=
"getMenuItems"
merger
=
"true"
/>
</
dubbo:service
>
|
或:(某個方法不合並結果,其它都合併結果)
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"*"
merger
=
"true"
>
<
dubbo:method
name
=
"getMenuItems"
merger
=
"false"
/>
</
dubbo:service
>
|
或:(指定合併策略,缺省根據返回值類型自動匹配,若是同一類型有兩個合併器時,需指定合併器的名稱)
參見:[合併結果擴展]
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"*"
>
<
dubbo:method
name
=
"getMenuItems"
merger
=
"mymerge"
/>
</
dubbo:service
>
|
或:(指定合併方法,將調用返回結果的指定方法進行合併,合併方法的參數類型必須是返回結果類型自己)
<
dubbo:reference
interface
=
"com.xxx.MenuService"
group
=
"*"
>
<
dubbo:method
name
=
"getMenuItems"
merger
=
".addAll"
/>
</
dubbo:service
>
|
參數驗證功能是基於JSR303實現的,用戶只需標識JSR303標準的驗證Annotation,並經過聲明filter來實現驗證。 |
2.1.0以上版本支持 |
驗證方式可擴展,參見:Validation擴展點
參數標註示例:
import
java.io.Serializable;
import
java.util.Date;
import
javax.validation.constraints.Future;
import
javax.validation.constraints.Max;
import
javax.validation.constraints.Min;
import
javax.validation.constraints.NotNull;
import
javax.validation.constraints.Past;
import
javax.validation.constraints.Pattern;
import
javax.validation.constraints.Size;
public
class
ValidationParameter
implements
Serializable {
private
static
final
long
serialVersionUID = 7158911668568000392L;
@NotNull
// 不容許爲空
@Size
(min =
1
, max =
20
)
// 長度或大小範圍
private
String name;
@NotNull
(groups = ValidationService.Save.
class
)
// 保存時不容許爲空,更新時容許爲空 ,表示不更新該字段
@Pattern
(regexp =
"^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$"
)
private
String email;
@Min
(
18
)
// 最小值
@Max
(
100
)
// 最大值
private
int
age;
@Past
// 必須爲一個過去的時間
private
Date loginDate;
@Future
// 必須爲一個將來的時間
private
Date expiryDate;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getEmail() {
return
email;
}
public
void
setEmail(String email) {
this
.email = email;
}
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
public
Date getLoginDate() {
return
loginDate;
}
public
void
setLoginDate(Date loginDate) {
this
.loginDate = loginDate;
}
public
Date getExpiryDate() {
return
expiryDate;
}
public
void
setExpiryDate(Date expiryDate) {
this
.expiryDate = expiryDate;
}
}
|
分組驗證示例:
public
interface
ValidationService {
// 缺省可按服務接口區分驗證場景,如:@NotNull(groups = ValidationService.class)
@interface
Save{}
// 與方法同名接口,首字母大寫,用於區分驗證場景,如:@NotNull(groups = ValidationService.Save.class),可選
void
save(ValidationParameter parameter);
void
update(ValidationParameter parameter);
}
|
關聯驗證示例:
import
javax.validation.GroupSequence;
public
interface
ValidationService {
@GroupSequence
(Update.
class
)
// 同時驗證Update組規則
@interface
Save{}
void
save(ValidationParameter parameter);
@interface
Update{}
void
update(ValidationParameter parameter);
}
|
參數驗證示例:
import
javax.validation.constraints.Min;
import
javax.validation.constraints.NotNull;
public
interface
ValidationService {
void
save(
@NotNull
ValidationParameter parameter);
// 驗證參數不爲空
void
delete(
@Min
(
1
)
int
id);
// 直接對基本類型參數驗證
}
|
在客戶端驗證參數:
<
dubbo:reference
id
=
"validationService"
interface
=
"com.alibaba.dubbo.examples.validation.api.ValidationService"
validation
=
"true"
/>
|
在服務器端驗證參數:
<
dubbo:service
interface
=
"com.alibaba.dubbo.examples.validation.api.ValidationService"
ref
=
"validationService"
validation
=
"true"
/>
|
驗證異常信息:
import
javax.validation.ConstraintViolationException;
import
javax.validation.ConstraintViolationException;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import
com.alibaba.dubbo.examples.validation.api.ValidationParameter;
import
com.alibaba.dubbo.examples.validation.api.ValidationService;
import
com.alibaba.dubbo.rpc.RpcException;
public
class
ValidationConsumer {
public
static
void
main(String[] args)
throws
Exception {
String config = ValidationConsumer.
class
.getPackage().getName().replace(
'.'
,
'/'
) +
"/validation-consumer.xml"
;
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(config);
context.start();
ValidationService validationService = (ValidationService)context.getBean(
"validationService"
);
// Error
try
{
parameter =
new
ValidationParameter();
validationService.save(parameter);
System.out.println(
"Validation ERROR"
);
}
catch
(RpcException e) {
// 拋出的是RpcException
ConstraintViolationException ve = (ConstraintViolationException) e.getCause();
// 裏面嵌了一個ConstraintViolationException
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
// 能夠拿到一個驗證錯誤詳細信息的集合
System.out.println(violations);
}
}
}
|
須要加入依賴:
<
dependency
>
<
groupId
>javax.validation</
groupId
>
<
artifactId
>validation-api</
artifactId
>
<
version
>1.0.0.GA</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.hibernate</
groupId
>
<
artifactId
>hibernate-validator</
artifactId
>
<
version
>4.2.0.Final</
version
>
</
dependency
>
|
結果緩存,用於加速熱門數據的訪問速度,Dubbo提供聲明式緩存,以減小用戶加緩存的工做量。 |
2.1.0以上版本支持 |
緩存類型可擴展,參見:CacheFactory擴展點
配置如:
<
dubbo:reference
interface
=
"com.foo.BarService"
cache
=
"lru"
/>
|
或:
<
dubbo:reference
interface
=
"com.foo.BarService"
>
<
dubbo:method
name
=
"findBar"
cache
=
"lru"
/>
</
dubbo:reference
>
|
泛接口調用方式主要用於客戶端沒有API接口及模型類元的狀況,參數及返回值中的全部POJO均用Map表示,一般用於框架集成,好比:實現一個通用的服務測試框架,可經過GenericService調用全部服務實現。 |
<
dubbo:reference
id
=
"barService"
interface
=
"com.foo.BarService"
generic
=
"true"
/>
|
GenericService barService = (GenericService) applicationContext.getBean(
"barService"
);
Object result = barService.$invoke(
"sayHello"
,
new
String[] {
"java.lang.String"
},
new
Object[] {
"World"
});
|
import
com.alibaba.dubbo.rpc.service.GenericService;
...
// 引用遠程服務
ReferenceConfig<GenericService> reference =
new
ReferenceConfig<GenericService>();
// 該實例很重量,裏面封裝了全部與註冊中心及服務提供方鏈接,請緩存
reference.setInterface(
"com.xxx.XxxService"
);
// 弱類型接口名
reference.setVersion(
"1.0.0"
);
reference.setGeneric(
true
);
// 聲明爲泛化接口
GenericService genericService = reference.get();
// 用com.alibaba.dubbo.rpc.service.GenericService能夠替代全部接口引用
// 基本類型以及Date,List,Map等不須要轉換,直接調用
Object result = genericService.$invoke(
"sayHello"
,
new
String[] {
"java.lang.String"
},
new
Object[] {
"world"
});
// 用Map表示POJO參數,若是返回值爲POJO也將自動轉成Map
Map<String, Object> person =
new
HashMap<String, Object>();
person.put(
"name"
,
"xxx"
);
person.put(
"password"
,
"yyy"
);
Object result = genericService.$invoke(
"findPerson"
,
new
String[]{
"com.xxx.Person"
},
new
Object[]{person});
// 若是返回POJO將自動轉成Map
...
|
假設存在POJO如:
package
com.xxx;
public
class
PersonImpl
implements
Person {
private
String name;
private
String password;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getPassword() {
return
password;
}
public
void
setPassword(String password) {
this
.password= password;
}
}
|
則POJO數據:
Person person =
new
PersonImpl();
person.setName(
"xxx"
);
person.setPassword(
"yyy"
);
|
可用下面Map表示:
Map<String, Object> map =
new
HashMap<String, Object>();
map.put(
"class"
,
"com.xxx.PersonImpl"
);
// 注意:若是參數類型是接口,或者List等丟失泛型,可經過class屬性指定類型。
map.put(
"name"
,
"xxx"
);
map.put(
"password"
,
"yyy"
);
|
泛接口實現方式主要用於服務器端沒有API接口及模型類元的狀況,參數及返回值中的全部POJO均用Map表示,一般用於框架集成,好比:實現一個通用的遠程服務Mock框架,可經過實現GenericService接口處理全部服務請求。 |
<
bean
id
=
"genericService"
class
=
"com.foo.MyGenericService"
/>
<
dubbo:service
interface
=
"com.foo.BarService"
ref
=
"genericService"
/>
|
package
com.foo;
public
class
MyGenericService
implements
GenericService {
public
Object $invoke(String methodName, String[] parameterTypes, Object[] args)
throws
GenericException {
if
(
"sayHello"
.equals(methodName)) {
return
"Welcome "
+ args[
0
];
}
}
}
|
...
GenericService xxxService =
new
XxxGenericService();
// 用com.alibaba.dubbo.rpc.service.GenericService能夠替代全部接口實現
ServiceConfig<GenericService> service =
new
ServiceConfig<GenericService>();
// 該實例很重量,裏面封裝了全部與註冊中心及服務提供方鏈接,請緩存
service.setInterface(
"com.xxx.XxxService"
);
// 弱類型接口名
service.setVersion(
"1.0.0"
);
service.setRef(xxxService);
// 指向一個通用服務實現
// 暴露及註冊服務
service.export();
|
回聲測試用於檢測服務是否可用,回聲測試按照正常請求流程執行,可以測試整個調用是否通暢,可用於監控。 |
全部服務自動實現EchoService接口,只需將任意服務引用強制轉型爲EchoService,便可使用。 |
<
dubbo:reference
id
=
"memberService"
interface
=
"com.xxx.MemberService"
/>
|
MemberService memberService = ctx.getBean(
"memberService"
);
// 遠程服務引用
EchoService echoService = (EchoService) memberService;
// 強制轉型爲EchoService
String status = echoService.$echo(
"OK"
);
// 回聲測試可用性
assert
(status.equals(
"OK"
))
|
上下文中存放的是當前調用過程當中所需的環境信息。 |
全部配置信息都將轉換爲URL的參數,參見《配置項一覽表》中的「對應URL參數」一列。 |
注意 RpcContext是一個ThreadLocal的臨時狀態記錄器,當接收到RPC請求,或發起RPC請求時,RpcContext的狀態都會變化。 好比:A調B,B再調C,則B機器上,在B調C以前,RpcContext記錄的是A調B的信息,在B調C以後,RpcContext記錄的是B調C的信息。 |
xxxService.xxx();
// 遠程調用
boolean
isConsumerSide = RpcContext.getContext().isConsumerSide();
// 本端是否爲消費端,這裏會返回true
String serverIP = RpcContext.getContext().getRemoteHost();
// 獲取最後一次調用的提供方IP地址
String application = RpcContext.getContext().getUrl().getParameter(
"application"
);
// 獲取當前服務配置信息,全部配置信息都將轉換爲URL的參數
// ...
yyyService.yyy();
// 注意:每發起RPC調用,上下文狀態會變化
// ...
|
public
class
XxxServiceImpl
implements
XxxService {
public
void
xxx() {
// 服務方法實現
boolean
isProviderSide = RpcContext.getContext().isProviderSide();
// 本端是否爲提供端,這裏會返回true
String clientIP = RpcContext.getContext().getRemoteHost();
// 獲取調用方IP地址
String application = RpcContext.getContext().getUrl().getParameter(
"application"
);
// 獲取當前服務配置信息,全部配置信息都將轉換爲URL的參數
// ...
yyyService.yyy();
// 注意:每發起RPC調用,上下文狀態會變化
boolean
isProviderSide = RpcContext.getContext().isProviderSide();
// 此時本端變成消費端,這裏會返回false
// ...
}
}
|
注:path,group,version,dubbo,token,timeout幾個key有特殊處理,請使用其它key值。 |
RpcContext.getContext().setAttachment(
"index"
,
"1"
);
// 隱式傳參,後面的遠程調用都會隱式將這些參數發送到服務器端,相似cookie,用於框架集成,不建議常規業務使用
xxxService.xxx();
// 遠程調用
// ...
|
【注】 setAttachment設置的KV,在完成下面一次遠程調用會被清空。即屢次遠程調用要屢次設置。
public
class
XxxServiceImpl
implements
XxxService {
public
void
xxx() {
// 服務方法實現
String index = RpcContext.getContext().getAttachment(
"index"
);
// 獲取客戶端隱式傳入的參數,用於框架集成,不建議常規業務使用
// ...
}
}
|
基於NIO的非阻塞實現並行調用,客戶端不須要啓動多線程便可完成並行調用多個遠程服務,相對多線程開銷較小。 |
2.0.6及其以上版本支持 |
配置聲明:
<
dubbo:reference
id
=
"fooService"
interface
=
"com.alibaba.foo.FooService"
>
<
dubbo:method
name
=
"findFoo"
async
=
"true"
/>
</
dubbo:reference
>
<
dubbo:reference
id
=
"barService"
interface
=
"com.alibaba.bar.BarService"
>
<
dubbo:method
name
=
"findBar"
async
=
"true"
/>
</
dubbo:reference
>
|
調用代碼:
fooService.findFoo(fooId);
// 此調用會當即返回null
Future<Foo> fooFuture = RpcContext.getContext().getFuture();
// 拿到調用的Future引用,當結果返回後,會被通知和設置到此Future。
barService.findBar(barId);
// 此調用會當即返回null
Future<Bar> barFuture = RpcContext.getContext().getFuture();
// 拿到調用的Future引用,當結果返回後,會被通知和設置到此Future。
// 此時findFoo和findBar的請求同時在執行,客戶端不須要啓動多線程來支持並行,而是藉助NIO的非阻塞完成。
Foo foo = fooFuture.get();
// 若是foo已返回,直接拿到返回值,不然線程wait住,等待foo返回後,線程會被notify喚醒。
Bar bar = barFuture.get();
// 同理等待bar返回。
// 若是foo須要5秒返回,bar須要6秒返回,實際只需等6秒,便可獲取到foo和bar,進行接下來的處理。
|
你也能夠設置是否等待消息發出:(異步老是不等待返回)
<
dubbo:method
name
=
"findFoo"
async
=
"true"
sent
=
"true"
/>
|
若是你只是想異步,徹底忽略返回值,能夠配置return="false",以減小Future對象的建立和管理成本:
<
dubbo:method
name
=
"findFoo"
async
=
"true"
return
=
"false"
/>
|
本地調用,使用了Injvm協議,是一個僞協議,它不開啓端口,不發起遠程調用,只在JVM內直接關聯,但執行Dubbo的Filter鏈。 |
Define injvm protocol:
<
dubbo:protocol
name
=
"injvm"
/>
|
Set default protocol:
<
dubbo:provider
protocol
=
"injvm"
/>
|
Set service protocol:
<
dubbo:service
protocol
=
"injvm"
/>
|
Use injvm first:
<
dubbo:consumer
injvm
=
"true"
.../>
<
dubbo:provider
injvm
=
"true"
.../>
|
或
<
dubbo:reference
injvm
=
"true"
.../>
<
dubbo:service
injvm
=
"true"
.../>
|
注意:服務暴露與服務引用都須要聲明injvm="true" |
從 dubbo 2.2.0 開始,每一個服務默認都會在本地暴露;在引用服務的時候,默認優先引用本地服務;若是但願引用遠程服務能夠使用一下配置強制引用遠程服務。
...
<
dubbo:reference
...
scope
=
"remote"
/>
...
|
參數回調方式與調用本地callback或listener相同,只須要在Spring的配置文件中聲明哪一個參數是callback類型便可,Dubbo將基於長鏈接生成反向代理,這樣就能夠從服務器端調用客戶端邏輯。 |
2.0.6及其以上版本支持 |
(1) 共享服務接口:
服務接口示例:
package
com.callback;
public
interface
CallbackService {
void
addListener(String key, CallbackListener listener);
}
|
package
com.callback;
public
interface
CallbackListener {
void
changed(String msg);
}
|
(2) 服務提供者:
服務提供者接口實現示例:
package
com.callback.impl;
import
java.text.SimpleDateFormat;
import
java.util.Date;
import
java.util.Map;
import
java.util.concurrent.ConcurrentHashMap;
import
com.callback.CallbackListener;
import
com.callback.CallbackService;
public
class
CallbackServiceImpl
implements
CallbackService {
private
final
Map<String, CallbackListener> listeners =
new
ConcurrentHashMap<String, CallbackListener>();
public
CallbackServiceImpl() {
Thread t =
new
Thread(
new
Runnable() {
public
void
run() {
while
(
true
) {
try
{
for
(Map.Entry<String, CallbackListener> entry : listeners.entrySet()){
try
{
entry.getValue().changed(getChanged(entry.getKey()));
}
catch
(Throwable t) {
listeners.remove(entry.getKey());
}
}
Thread.sleep(
5000
);
// 定時觸發變動通知
}
catch
(Throwable t) {
// 防護容錯
t.printStackTrace();
}
}
}
});
t.setDaemon(
true
);
t.start();
}
public
void
addListener(String key, CallbackListener listener) {
listeners.put(key, listener);
listener.changed(getChanged(key));
// 發送變動通知
}
private
String getChanged(String key) {
return
"Changed: "
+
new
SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss"
).format(
new
Date());
}
}
|
服務提供者配置示例:
<
bean
id
=
"callbackService"
class
=
"com.callback.impl.CallbackServiceImpl"
/>
<
dubbo:service
interface
=
"com.callback.CallbackService"
ref
=
"callbackService"
connections
=
"1"
callbacks
=
"1000"
>
<
dubbo:method
name
=
"addListener"
>
<
dubbo:argument
index
=
"1"
callback
=
"true"
/>
<!--也能夠經過指定類型的方式-->
<!--<dubbo:argument type="com.demo.CallbackListener" callback="true" />-->
</
dubbo:method
>
</
dubbo:service
>
|
(2) 服務消費者:
服務消費者配置示例:
<
dubbo:reference
id
=
"callbackService"
interface
=
"com.callback.CallbackService"
/>
|
服務消費者調用示例:
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(
"classpath:consumer.xml"
);
context.start();
CallbackService callbackService = (CallbackService) context.getBean(
"callbackService"
);
callbackService.addListener(
"http://10.20.160.198/wiki/display/dubbo/foo.bar"
,
new
CallbackListener(){
public
void
changed(String msg) {
System.out.println(
"callback1:"
+ msg);
}
});
|
在調用以前,調用以後,出現異常時,會觸發oninvoke, onreturn, onthrow三個事件,能夠配置當事件發生時,通知哪一個類的哪一個方法。 |
支持版本:2.0.7以後 |
(1) 服務提供者與消費者共享服務接口:
interface
IDemoService {
public
Person get(
int
id);
}
|
(2) 服務提供者實現:
class
NormalDemoService
implements
IDemoService {
public
Person get(
int
id) {
return
new
Person(id,
"charles`son"
,
4
);
}
}
|
(3) 服務提供者配置:
<
dubbo:application
name
=
"rpc-callback-demo"
/>
<
bean
id
=
"demoService"
class
=
"com.alibaba.dubbo.callback.implicit.NormalDemoService"
/>
<
dubbo:service
interface
=
"com.alibaba.dubbo.callback.implicit.IDemoService"
ref
=
"demoService"
version
=
"1.0.0"
group
=
"cn"
/>
|
(4) 服務消費者Callback接口及實現:
interface
Nofify {
public
void
onreturn(Person msg, Integer id);
public
void
onthrow(Throwable ex, Integer id);
}
|
class
NofifyImpl
implements
Nofify {
public
Map<Integer, Person> ret =
new
HashMap<Integer, Person>();
public
Map<Integer, Throwable> errors =
new
HashMap<Integer, Throwable>();
public
void
onreturn(Person msg, Integer id) {
System.out.println(
"onreturn:"
+ msg);
ret.put(id, msg);
}
public
void
onthrow(Throwable ex, Integer id) {
errors.put(id, ex);
}
}
|
(5) 服務消費者Callback接口及實現:
<
bean
id
=
"demoCallback"
class
=
"com.alibaba.dubbo.callback.implicit.NofifyImpl"
/>
<
dubbo:reference
id
=
"demoService"
interface
=
"com.alibaba.dubbo.callback.implicit.IDemoService"
version
=
"1.0.0"
group
=
"cn"
>
<
dubbo:method
name
=
"get"
async
=
"true"
onreturn
=
"demoCallback.onreturn"
onthrow
=
"demoCallback.onthrow"
/>
</
dubbo:reference
>
|
注: callback與async功能正交分解: async=true,表示結果是否立刻返回. onreturn 表示是否須要回調. 組合狀況:(async=false 默認) |
(6) TEST CASE:
IDemoService demoService = (IDemoService) context.getBean(
"demoService"
);
NofifyImpl notify = (NofifyImpl) context.getBean(
"demoCallback"
);
int
requestId =
2
;
Person ret = demoService.get(requestId);
Assert.assertEquals(
null
, ret);
//for Test:只是用來講明callback正常被調用,業務具體實現自行決定.
for
(
int
i =
0
; i <
10
; i++) {
if
(!notify.ret.containsKey(requestId)) {
Thread.sleep(
200
);
}
else
{
break
;
}
}
Assert.assertEquals(requestId, notify.ret.get(requestId).getId());
|
遠程服務後,客戶端一般只剩下接口,而實現全在服務器端,但提供方有些時候想在客戶端也執行部分邏輯,好比:作ThreadLocal緩存,提早驗證參數,調用失敗後僞造容錯數據等等,此時就須要在API中帶上Stub,客戶端生成Proxy實,會把Proxy經過構造函數傳給Stub,而後把Stub暴露組給用戶,Stub能夠決定要不要去調Proxy。 |
Stub必須有可傳入Proxy的構造函數。 |
<
dubbo:service
interface
=
"com.foo.BarService"
stub
=
"true"
/>
|
Or:
<
dubbo:service
interface
=
"com.foo.BarService"
stub
=
"com.foo.BarServiceStub"
/>
|
api.jar:
com.foo.BarService
com.foo.BarServiceStub // 在API旁邊放一個Stub實現,它實現BarService接口,並有一個傳入遠程BarService實例的構造函數
|
package
com.foo
public
class
BarServiceStub
implements
BarService {
private
final
BarService barService;
// 構造函數傳入真正的遠程代理對象
public
(BarService barService) {
this
.barService = barService;
}
public
String sayHello(String name) {
// 此代碼在客戶端執行
// 你能夠在客戶端作ThreadLocal本地緩存,或預先驗證參數是否合法,等等
try
{
return
barService.sayHello(name);
}
catch
(Exception e) {
// 你能夠容錯,能夠作任何AOP攔截事項
return
"容錯數據"
;
}
}
}
|
Mock一般用於服務降級,好比某驗權服務,當服務提供方所有掛掉後,客戶端不拋出異常,而是經過Mock數據返回受權失敗。 |
Mock是Stub的一個子集,便於服務提供方在客戶端執行容錯邏輯,因常常須要在出現RpcException(好比網絡失敗,超時等)時進行容錯,而在出現業務異常(好比登陸用戶名密碼錯誤)時不須要容錯,若是用Stub,可能就須要捕獲並依賴RpcException類,而用Mock就能夠不依賴RpcException,由於它的約定就是隻有出現RpcException時才執行。 |
<
dubbo:service
interface
=
"com.foo.BarService"
mock
=
"true"
/>
|
Or:
<
dubbo:service
interface
=
"com.foo.BarService"
mock
=
"com.foo.BarServiceMock"
/>
|
api.jar:
com.foo.BarService
com.foo.BarServiceMock // 在API旁邊放一個Mock實現,它實現BarService接口,並有一個無參構造函數
|
package
com.foo
public
class
BarServiceMock
implements
BarService {
public
String sayHello(String name) {
// 你能夠僞造容錯數據,此方法只在出現RpcException時被執行
return
"容錯數據"
;
}
}
|
若是服務的消費方常常須要try-catch捕獲異常,如:
Offer offer =
null
;
try
{
offer = offerService.findOffer(offerId);
}
catch
(RpcException e) {
logger.error(e);
}
|
請考慮改成Mock實現,並在Mock中return null。
若是隻是想簡單的忽略異常,在2.0.11以上版本可用:
<
dubbo:service
interface
=
"com.foo.BarService"
mock
=
"return null"
/>
|
若是你的服務須要Warmup時間,好比初始化緩存,等待相關資源就位等,能夠使用delay進行延遲暴露。 |
延遲5秒暴露服務:
<
dubbo:service
delay
=
"5000"
/>
|
延遲到Spring初始化完成後,再暴露服務:(基於Spring的ContextRefreshedEvent事件觸發暴露)
<
dubbo:service
delay
=
"-1"
/>
|
Spring2.x初始化死鎖問題 在Spring解析到<dubbo:service />時,就已經向外暴露了服務,而Spring還在接着初始化其它Bean。 若是這時有請求進來,而且服務的實現類裏有調用applicationContext.getBean()的用法。 1. 請求線程的applicationContext.getBean()調用,先同步singletonObjects判斷Bean是否存在,不存在就同步beanDefinitionMap進行初始化,並再次同步singletonObjects寫入Bean實例緩存。 這樣就致使getBean線程,先鎖singletonObjects,再鎖beanDefinitionMap,再次鎖singletonObjects。 |
規避辦法 1. 強烈建議不要在服務的實現類中有applicationContext.getBean()的調用,所有采用IoC注入的方式使用Spring的Bean。 2. 若是實在要調getBean(),能夠將Dubbo的配置放在Spring的最後加載。 3. 若是不想依賴配置順序,能夠使用<dubbo:provider deplay=」-1」 />,使Dubbo在Spring容器初始化完後,再暴露服務。 4. 若是大量使用getBean(),至關於已經把Spring退化爲工廠模式在用,能夠將Dubbo的服務隔離單獨的Spring容器。 |
限制com.foo.BarService的每一個方法,服務器端併發執行(或佔用線程池線程數)不能超過10個:
<
dubbo:service
interface
=
"com.foo.BarService"
executes
=
"10"
/>
|
限制com.foo.BarService的sayHello方法,服務器端併發執行(或佔用線程池線程數)不能超過10個:
<
dubbo:service
interface
=
"com.foo.BarService"
>
<
dubbo:method
name
=
"sayHello"
executes
=
"10"
/>
</
dubbo:service
>
|
限制com.foo.BarService的每一個方法,每客戶端併發執行(或佔用鏈接的請求數)不能超過10個:
<
dubbo:service
interface
=
"com.foo.BarService"
actives
=
"10"
/>
|
Or:
<
dubbo:reference
interface
=
"com.foo.BarService"
actives
=
"10"
/>
|
限制com.foo.BarService的sayHello方法,每客戶端併發執行(或佔用鏈接的請求數)不能超過10個:
<
dubbo:service
interface
=
"com.foo.BarService"
>
<
dubbo:method
name
=
"sayHello"
actives
=
"10"
/>
</
dubbo:service
>
|
Or:
<
dubbo:reference
interface
=
"com.foo.BarService"
>
<
dubbo:method
name
=
"sayHello"
actives
=
"10"
/>
</
dubbo:service
>
|
若是<dubbo:service>和<dubbo:reference>都配了actives,<dubbo:reference>優先,參見:配置的覆蓋策略。
Load Balance均衡:
配置服務的客戶端的loadbalance屬性爲leastactive,此Loadbalance會調用併發數最小的Provider(Consumer端併發數)。
<
dubbo:reference
interface
=
"com.foo.BarService"
loadbalance
=
"leastactive"
/>
|
Or:
<
dubbo:service
interface
=
"com.foo.BarService"
loadbalance
=
"leastactive"
/>
|
限制服務器端接受的鏈接不能超過10個:(以鏈接在Server上,因此配置在Provider上)
<
dubbo:provider
protocol
=
"dubbo"
accepts
=
"10"
/>
|
<
dubbo:protocol
name
=
"dubbo"
accepts
=
"10"
/>
|
限制客戶端服務使用鏈接鏈接數:(若是是長鏈接,好比Dubbo協議,connections表示該服務對每一個提供者創建的長鏈接數)
<
dubbo:reference
interface
=
"com.foo.BarService"
connections
=
"10"
/>
|
Or:
<
dubbo:service
interface
=
"com.foo.BarService"
connections
=
"10"
/>
|
若是<dubbo:service>和<dubbo:reference>都配了connections,<dubbo:reference>優先,參見:配置的覆蓋策略。
延遲鏈接,用於減小長鏈接數,當有調用發起時,再建立長鏈接。 |
只對使用長鏈接的dubbo協議生效。 |
<
dubbo:protocol
name
=
"dubbo"
lazy
=
"true"
/>
|
粘滯鏈接用於有狀態服務,儘量讓客戶端老是向同一提供者發起調用,除非該提供者掛了,再連另外一臺。 |
<
dubbo:protocol
name
=
"dubbo"
sticky
=
"true"
/>
|
能夠全局設置開啓令牌驗證:
<!--隨機token令牌,使用UUID生成-->
<
dubbo:provider
interface
=
"com.foo.BarService"
token
=
"true"
/>
|
<!--固定token令牌,至關於密碼-->
<
dubbo:provider
interface
=
"com.foo.BarService"
token
=
"123456"
/>
|
也可在服務級別設置:
<!--隨機token令牌,使用UUID生成-->
<
dubbo:service
interface
=
"com.foo.BarService"
token
=
"true"
/>
|
<!--固定token令牌,至關於密碼-->
<
dubbo:service
interface
=
"com.foo.BarService"
token
=
"123456"
/>
|
還可在協議級別設置:
<!--隨機token令牌,使用UUID生成-->
<
dubbo:protocol
name
=
"dubbo"
token
=
"true"
/>
|
<!--固定token令牌,至關於密碼-->
<
dubbo:protocol
name
=
"dubbo"
token
=
"123456"
/>
|
2.2.0以上版本支持 |
路由規則擴展點:路由擴展 |
向註冊中心寫入路由規則:(一般由監控中心或治理中心的頁面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"condition://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="
+ URL.encode(
"http://10.20.160.198/wiki/display/dubbo/host = 10.20.153.10 => host = 10.20.153.11"
) + "));
|
其中:
(#)
基於條件表達式的路由規則,如:
host =
10.20
.
153.10
=> host =
10.20
.
153.11
|
規則:
表達式:
示例:
1. 排除預發佈機:
=> host !=
172.22
.
3.91
|
2. 白名單:(注意:一個服務只能有一條白名單規則,不然兩條規則交叉,就都被篩選掉了)
host !=
10.20
.
153.10
,
10.20
.
153.11
=>
|
3. 黑名單:
host =
10.20
.
153.10
,
10.20
.
153.11
=>
|
4. 服務寄宿在應用上,只暴露一部分的機器,防止整個集羣掛掉:
=> host =
172.22
.
3.1
*,
172.22
.
3.2
*
|
5. 爲重要應用提供額外的機器:
application != kylin => host !=
172.22
.
3.95
,
172.22
.
3.96
|
6. 讀寫分離:
method = find*,list*,get*,is* => host =
172.22
.
3.94
,
172.22
.
3.95
,
172.22
.
3.96
|
method != find*,list*,get*,is* => host =
172.22
.
3.97
,
172.22
.
3.98
|
7. 先後臺分離:
application = bops => host =
172.22
.
3.91
,
172.22
.
3.92
,
172.22
.
3.93
|
application != bops => host =
172.22
.
3.94
,
172.22
.
3.95
,
172.22
.
3.96
|
8. 隔離不一樣機房網段:
host !=
172.22
.
3
.* => host !=
172.22
.
3
.*
|
9. 提供者與消費者部署在同集羣內,本機只訪問本機的服務:
=> host = $host
|
(#)
支持JDK腳本引擎的全部腳本,好比:javascript,jruby,groovy等,經過type=javascript參數設置腳本類型,缺省爲javascript。 |
腳本沒有沙箱約束,可執行任意代碼,存在後門風險 |
"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="
+ URL.encode(
"function route(invokers) { ... } (invokers)"
)
|
基於腳本引擎的路由規則,如:
function
route(invokers) {
var
result =
new
java.util.ArrayList(invokers.size());
for
(i = 0; i < invokers.size(); i ++) {
if
(
"http://10.20.160.198/wiki/display/dubbo/10.20.153.10"
.equals(invokers.get(i).getUrl().getHost())) {
result.add(invokers.get(i));
}
}
return
result;
} (invokers);
// 表示當即執行方法
|
2.2.0以上版本支持 |
向註冊中心寫入動態配置覆蓋規則:(一般由監控中心或治理中心的頁面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&timeout=1000"
));
|
其中:
示例:
1. 禁用提供者:(一般用於臨時踢除某臺提供者機器,類似的,禁止消費者訪問請使用路由規則)
override:
//10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&disbaled=true
|
2. 調整權重:(一般用於容量評估,缺省權重爲100)
override:
//10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&weight=200
|
3. 調整負載均衡策略:(缺省負載均衡策略爲random)
override:
//10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&loadbalance=leastactive
|
4. 服務降級:(一般用於臨時屏蔽某個出錯的非關鍵服務)
override:
//0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null
|
2.2.0以上版本支持 |
參見:配置規則 |
向註冊中心寫入動態配置覆蓋規則:(經過由監控中心或治理中心的頁面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"
));
|
其中:
mock=force:
return
+
null
|
還能夠改成:
mock=fail:
return
+
null
|
Dubbo是經過JDK的ShutdownHook來完成優雅停機的,因此若是用戶使用"kill -9 PID"等強制關閉指令,是不會執行優雅停機的,只有經過"kill PID"時,纔會執行。 |
原理:
設置優雅停機超時時間,缺省超時時間是10秒:(超時則強制關閉)
<
dubbo:application
...>
<
dubbo:parameter
key
=
"shutdown.timeout"
value
=
"60000"
/>
<!-- 單位毫秒 -->
</
dubbo:application
>
|
若是ShutdownHook不能生效,能夠自行調用:
ProtocolConfig.destroyAll();
|
缺省主機IP查找順序:
註冊的地址若是獲取不正確,好比須要註冊公網地址,能夠:
1. 能夠在/etc/hosts中加入:機器名 公網IP,好比:
test1
205.182
.
23.201
|
2. 在dubbo.xml中加入主機地址的配置:
|
3. 或在dubbo.properties中加入主機地址的配置:
dubbo.protocol.host=
205.182
.
23.201
|
缺省主機端口與協議相關:
主機端口配置:
1. 在dubbo.xml中加入主機地址的配置:
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
>
|
3. 或在dubbo.properties中加入主機地址的配置:
dubbo.protocol.dubbo.port=
20880
|
2.2.1以上版本支持 |
擴展點:日誌適配擴展 |
缺省自動查找:
能夠經過如下方式配置日誌輸出策略:
java -Ddubbo.application.logger=log4j
|
dubbo.application.logger=log4j
|
<dubbo:application logger=
"log4j"
/>
|
若是你想記錄每一次請求信息,可開啓訪問日誌,相似於apache的訪問日誌。 |
此日誌量比較大,請注意磁盤容量。 |
將訪問日誌輸出到當前應用的log4j日誌:
<
dubbo:protocol
accesslog
=
"true"
/>
|
將訪問日誌輸出到指定文件:
|
服務容器是一個standalone的啓動程序,由於後臺服務不須要Tomcat或JBoss等Web容器的功能,若是硬要用Web容器去加載服務提供方,增長複雜性,也浪費資源。 |
服務容器只是一個簡單的Main方法,並加載一個簡單的Spring容器,用於暴露服務。 |
服務容器的加載內容能夠擴展,內置了spring, jetty, log4j等加載,可經過Container擴展點進行擴展,參見:Container |
容器啓動
如:(缺省只加載spring)
java com.alibaba.dubbo.container.Main
|
或:(經過main函數參數傳入要加載的容器)
java com.alibaba.dubbo.container.Main spring jetty log4j
|
或:(經過JVM啓動參數傳入要加載的容器)
java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
|
或:(經過classpath下的dubbo.properties配置傳入要加載的容器)
dubbo.container=spring,jetty,log4j
|
ReferenceConfig實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,須要緩存,不然重複生成ReferenceConfig可能形成性能問題而且會有內存和鏈接泄漏。API方式編程時,容易忽略此問題。
Dubbo 2.4.0+版本,提供了簡單的工具類ReferenceConfigCache用於緩存ReferenceConfig實例。
使用方式以下:
ReferenceConfig<XxxService> reference =
new
ReferenceConfig<XxxService>();
reference.setInterface(XxxService.
class
);
reference.setVersion(
"1.0.0"
);
......
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
XxxService xxxService = cache.get(reference);
// cache.get方法中會Cache Reference對象,而且調用ReferenceConfig.get方法啓動ReferenceConfig
// 注意! Cache會持有ReferenceConfig,不要在外部再調用ReferenceConfig的destroy方法,致使Cache內的ReferenceConfig失效!
// 使用xxxService對象
xxxService.sayHello();
|
消除Cache中的ReferenceConfig,銷燬ReferenceConfig並釋放對應的資源。
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
cache.destroy(reference);
|
缺省ReferenceConfigCache把相同服務Group、接口、版本的ReferenceConfig認爲是相同,緩存一份。即以服務Group、接口、版本爲緩存的Key。
能夠修改這個策略,在ReferenceConfigCache.getCache時,傳一個KeyGenerator。詳見ReferenceConfigCache類的方法。
KeyGenerator keyGenerator =
new
...
ReferenceConfigCache cache = ReferenceConfigCache.getCache(keyGenerator );
|
基於JTA/XA規範實現。 |
暫未實現。 |
兩階段提交:
Dubbo的常規功能,都保持零侵入,但有些功能不得不用API侵入才能實現。 |
Dubbo中除這裏聲明之外的接口或類,都是內部接口或擴展接口,普通用戶請不要直接依賴,不然升級版本可能出現不兼容。 |
API彙總以下:
注意:只有group,interface,version是服務的匹配條件,三者決定是否是同一個服務,其它配置項均爲調優和治理參數。
全部配置項分爲三大類,參見下表中的"做用"一列。
全部配置最終都將轉換爲URL表示,並由服務提供方生成,經註冊中心傳遞給消費方,各屬性對應URL的參數,參見配置項一覽表中的"對應URL參數"列。
URL格式:
protocol://username:password@host:port/path?key=value&key=value
Schema: http://code.alibabatech.com/schema/dubbo/dubbo.xsd
服務提供者暴露服務配置:
配置類:com.alibaba.dubbo.config.ServiceConfig
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:service> | interface | class | 必填 | 服務發現 | 服務接口名 | 1.0.0以上版本 | ||
<dubbo:service> | ref | object | 必填 | 服務發現 | 服務對象實現引用 | 1.0.0以上版本 | ||
<dubbo:service> | version | version | string | 可選 | 0.0.0 | 服務發現 | 服務版本,建議使用兩位數字版本,如:1.0,一般在接口不兼容時版本號才須要升級 | 1.0.0以上版本 |
<dubbo:service> | group | group | string | 可選 | 服務發現 | 服務分組,當一個接口有多個實現,能夠用分組區分 | 1.0.7以上版本 | |
<dubbo:service> | path | <path> | string | 可選 | 缺省爲接口名 | 服務發現 | 服務路徑 (注意:1.0不支持自定義路徑,老是使用接口名,若是有1.0調2.0,配置服務路徑可能不兼容) | 1.0.12以上版本 |
<dubbo:service> | delay | delay | int | 可選 | 0 | 性能調優 | 延遲註冊服務時間(毫秒) ,設爲-1時,表示延遲到Spring容器初始化完成時暴露服務 | 1.0.14以上版本 |
<dubbo:service> | timeout | timeout | int | 可選 | 1000 | 性能調優 | 遠程服務調用超時時間(毫秒) | 2.0.0以上版本 |
<dubbo:service> | retries | retries | int | 可選 | 2 | 性能調優 | 遠程服務調用重試次數,不包括第一次調用,不須要重試請設爲0 | 2.0.0以上版本 |
<dubbo:service> | connections | connections | int | 可選 | 100 | 性能調優 | 對每一個提供者的最大鏈接數,rmi、http、hessian等短鏈接協議表示限制鏈接數,dubbo等長鏈接協表示創建的長鏈接個數 | 2.0.0以上版本 |
<dubbo:service> | loadbalance | loadbalance | string | 可選 | random | 性能調優 | 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用 | 2.0.0以上版本 |
<dubbo:service> | async | async | boolean | 可選 | false | 性能調優 | 是否缺省異步執行,不可靠異步,只是忽略返回值,不阻塞執行線程 | 2.0.0以上版本 |
<dubbo:service> | stub | stub | class/boolean | 可選 | false | 服務治理 | 設爲true,表示使用缺省代理類名,即:接口名 + Local後綴,服務接口客戶端本地代理類名,用於在客戶端執行本地邏輯,如本地緩存等,該本地代理類的構造函數必須容許傳入遠程代理對象,構造函數如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 |
<dubbo:service> | mock | mock | class/boolean | 可選 | false | 服務治理 | 設爲true,表示使用缺省Mock類名,即:接口名 + Mock後綴,服務接口調用失敗Mock實現類,該Mock類必須有一個無參構造函數,與Local的區別在於,Local老是被執行,而Mock只在出現非業務異常(好比超時,網絡異常等)時執行,Local在遠程調用以前執行,Mock在遠程調用後執行。 | 2.0.0以上版本 |
<dubbo:service> | token | token | string/boolean | 可選 | false | 服務治理 | 令牌驗證,爲空表示不開啓,若是爲true,表示隨機生成動態令牌,不然使用靜態令牌,令牌的做用是防止消費者繞過註冊中心直接訪問,保證註冊中心的受權功能有效,若是使用點對點調用,需關閉令牌功能 | 2.0.0以上版本 |
<dubbo:service> | registry | string | 可選 | 缺省向全部registry註冊 | 配置關聯 | 向指定註冊中心註冊,在多個註冊中心時使用,值爲<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔,若是不想將該服務註冊到任何registry,可將值設爲N/A | 2.0.0以上版本 | |
<dubbo:service> | provider | string | 可選 | 缺使用第一個provider配置 | 配置關聯 | 指定provider,值爲<dubbo:provider>的id屬性 | 2.0.0以上版本 | |
<dubbo:service> | deprecated | deprecated | boolean | 可選 | false | 服務治理 | 服務是否過期,若是設爲true,消費方引用時將打印服務過期警告error日誌 | 2.0.5以上版本 |
<dubbo:service> | dynamic | dynamic | boolean | 可選 | true | 服務治理 | 服務是否動態註冊,若是設爲false,註冊後將顯示後disable狀態,需人工啓用,而且服務提供者中止時,也不會自動取消冊,需人工禁用。 | 2.0.5以上版本 |
<dubbo:service> | accesslog | accesslog | string/boolean | 可選 | false | 服務治理 | 設爲true,將向logger中輸出訪問日誌,也可填寫訪問日誌文件路徑,直接把訪問日誌輸出到指定文件 | 2.0.5以上版本 |
<dubbo:service> | owner | owner | string | 可選 | 服務治理 | 服務負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.0.5以上版本 | |
<dubbo:service> | document | document | string | 可選 | 服務治理 | 服務文檔URL | 2.0.5以上版本 | |
<dubbo:service> | weight | weight | int | 可選 | 性能調優 | 服務權重 | 2.0.5以上版本 | |
<dubbo:service> | executes | executes | int | 可選 | 0 | 性能調優 | 服務提供者每服務每方法最大可並行執行請求數 | 2.0.5以上版本 |
<dubbo:service> | actives | actives | int | 可選 | 0 | 性能調優 | 每服務消費者每服務每方法最大併發調用數 | 2.0.5以上版本 |
<dubbo:service> | proxy | proxy | string | 可選 | javassist | 性能調優 | 生成動態代理方式,可選:jdk/javassist | 2.0.5以上版本 |
<dubbo:service> | cluster | cluster | string | 可選 | failover | 性能調優 | 集羣方式,可選:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:service> | filter | service.filter | string | 可選 | default | 性能調優 | 服務提供方遠程調用過程攔截器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 |
<dubbo:service> | listener | exporter.listener | string | 可選 | default | 性能調優 | 服務提供方導出服務監聽器名稱,多個名稱用逗號分隔 | |
<dubbo:service> | protocol | string | 可選 | 配置關聯 | 使用指定的協議暴露服務,在多協議時使用,值爲<dubbo:protocol>的id屬性,多個協議ID用逗號分隔 | 2.0.5以上版本 | ||
<dubbo:service> | layer | layer | string | 可選 | 服務治理 | 服務提供者所在的分層。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:service> | register | register | boolean | 可選 | true | 服務治理 | 該協議的服務是否註冊到註冊中心 | 2.0.8以上版本 |
服務消費者引用服務配置:
配置類:com.alibaba.dubbo.config.ReferenceConfig
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:reference> | id | string | 必填 | 配置關聯 | 服務引用BeanId | 1.0.0以上版本 | ||
<dubbo:reference> | interface | class | 必填 | 服務發現 | 服務接口名 | 1.0.0以上版本 | ||
<dubbo:reference> | version | version | string | 可選 | 服務發現 | 服務版本,與服務提供者的版本一致 | 1.0.0以上版本 | |
<dubbo:reference> | group | group | string | 可選 | 服務發現 | 服務分組,當一個接口有多個實現,能夠用分組區分,必需和服務提供方一致 | 1.0.7以上版本 | |
<dubbo:reference> | timeout | timeout | long | 可選 | 缺省使用<dubbo:consumer>的timeout | 性能調優 | 服務方法調用超時時間(毫秒) | 1.0.5以上版本 |
<dubbo:reference> | retries | retries | int | 可選 | 缺省使用<dubbo:consumer>的retries | 性能調優 | 遠程服務調用重試次數,不包括第一次調用,不須要重試請設爲0 | 2.0.0以上版本 |
<dubbo:reference> | connections | connections | int | 可選 | 缺省使用<dubbo:consumer>的connections | 性能調優 | 對每一個提供者的最大鏈接數,rmi、http、hessian等短鏈接協議表示限制鏈接數,dubbo等長鏈接協表示創建的長鏈接個數 | 2.0.0以上版本 |
<dubbo:reference> | loadbalance | loadbalance | string | 可選 | 缺省使用<dubbo:consumer>的loadbalance | 性能調優 | 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用 | 2.0.0以上版本 |
<dubbo:reference> | async | async | boolean | 可選 | 缺省使用<dubbo:consumer>的async | 性能調優 | 是否異步執行,不可靠異步,只是忽略返回值,不阻塞執行線程 | 2.0.0以上版本 |
<dubbo:reference> | generic | generic | boolean | 可選 | 缺省使用<dubbo:consumer>的generic | 服務治理 | 是否缺省泛化接口,若是爲泛化接口,將返回GenericService | 2.0.0以上版本 |
<dubbo:reference> | check | check | boolean | 可選 | 缺省使用<dubbo:consumer>的check | 服務治理 | 啓動時檢查提供者是否存在,true報錯,false忽略 | 2.0.0以上版本 |
<dubbo:reference> | url | <url> | string | 可選 | 服務治理 | 點對點直連服務提供者地址,將繞過註冊中心 | 1.0.6以上版本 | |
<dubbo:reference> | stub | stub | class/boolean | 可選 | 服務治理 | 服務接口客戶端本地代理類名,用於在客戶端執行本地邏輯,如本地緩存等,該本地代理類的構造函數必須容許傳入遠程代理對象,構造函數如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 | |
<dubbo:reference> | mock | mock | class/boolean | 可選 | 服務治理 | 服務接口調用失敗Mock實現類名,該Mock類必須有一個無參構造函數,與Local的區別在於,Local老是被執行,而Mock只在出現非業務異常(好比超時,網絡異常等)時執行,Local在遠程調用以前執行,Mock在遠程調用後執行。 | Dubbo1.0.13及其以上版本支持 | |
<dubbo:reference> | cache | cache | string/boolean | 可選 | 服務治理 | 以調用參數爲key,緩存返回結果,可選:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:reference> | validation | validation | boolean | 可選 | 服務治理 | 是否啓用JSR303標準註解驗證,若是啓用,將對方法參數上的註解進行校驗 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:reference> | proxy | proxy | boolean | 可選 | javassist | 性能調優 | 選擇動態代理實現策略,可選:javassist, jdk | 2.0.2以上版本 |
<dubbo:reference> | client | client | string | 可選 | 性能調優 | 客戶端傳輸類型設置,如Dubbo協議的netty或mina。 | Dubbo2.0.0以上版本支持 | |
<dubbo:reference> | registry | string | 可選 | 缺省將從全部註冊中心獲服務列表後合併結果 | 配置關聯 | 從指定註冊中心註冊獲取服務列表,在多個註冊中心時使用,值爲<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔 | 2.0.0以上版本 | |
<dubbo:reference> | owner | owner | string | 可選 | 服務治理 | 調用服務負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.0.5以上版本 | |
<dubbo:reference> | actives | actives | int | 可選 | 0 | 性能調優 | 每服務消費者每服務每方法最大併發調用數 | 2.0.5以上版本 |
<dubbo:reference> | cluster | cluster | string | 可選 | failover | 性能調優 | 集羣方式,可選:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:reference> | filter | reference.filter | string | 可選 | default | 性能調優 | 服務消費方遠程調用過程攔截器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 |
<dubbo:reference> | listener | invoker.listener | string | 可選 | default | 性能調優 | 服務消費方引用服務監聽器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 |
<dubbo:reference> | layer | layer | string | 可選 | 服務治理 | 服務調用者所在的分層。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:reference> | init | init | boolean | 可選 | false | 性能調優 | 是否在afterPropertiesSet()時飢餓初始化引用,不然等到有人注入或引用該實例時再初始化。 | 2.0.10以上版本 |
<dubbo:reference> | protocol | protocol | string | 可選 | 服力治理 | 只調用指定協議的服務提供方,其它協議忽略。 | 2.2.0以上版本 |
服務提供者協議配置:
配置類:com.alibaba.dubbo.config.ProtocolConfig
說明:若是須要支持多協議,能夠聲明多個<dubbo:protocol>標籤,並在<dubbo:service>中經過protocol屬性指定使用的協議。
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:protocol> | id | string | 可選 | dubbo | 配置關聯 | 協議BeanId,能夠在<dubbo:service protocol="">中引用此ID,若是ID不填,缺省和name屬性值同樣,重複則在name後加序號。 | 2.0.5以上版本 | |
<dubbo:protocol> | name | <protocol> | string | 必填 | dubbo | 性能調優 | 協議名稱 | 2.0.5以上版本 |
<dubbo:protocol> | port | <port> | int | 可選 | dubbo協議缺省端口爲20880,rmi協議缺省端口爲1099,http和hessian協議缺省端口爲80 若是配置爲-1 或者 沒有配置port,則會分配一個沒有被佔用的端口。Dubbo 2.4.0+,分配的端口在協議缺省端口的基礎上增加,確保端口段可控。 |
服務發現 | 服務端口 | 2.0.5以上版本 |
<dubbo:protocol> | host | <host> | string | 可選 | 自動查找本機IP | 服務發現 | -服務主機名,多網卡選擇或指定VIP及域名時使用,爲空則自動查找本機IP,-建議不要配置,讓Dubbo自動獲取本機IP | 2.0.5以上版本 |
<dubbo:protocol> | threadpool | threadpool | string | 可選 | fixed | 性能調優 | 線程池類型,可選:fixed/cached | 2.0.5以上版本 |
<dubbo:protocol> | threads | threads | int | 可選 | 100 | 性能調優 | 服務線程池大小(固定大小) | 2.0.5以上版本 |
<dubbo:protocol> | iothreads | threads | int | 可選 | cpu個數+1 | 性能調優 | io線程池大小(固定大小) | 2.0.5以上版本 |
<dubbo:protocol> | accepts | accepts | int | 可選 | 0 | 性能調優 | 服務提供方最大可接受鏈接數 | 2.0.5以上版本 |
<dubbo:protocol> | payload | payload | int | 可選 | 88388608(=8M) | 性能調優 | 請求及響應數據包大小限制,單位:字節 | 2.0.5以上版本 |
<dubbo:protocol> | codec | codec | string | 可選 | dubbo | 性能調優 | 協議編碼方式 | 2.0.5以上版本 |
<dubbo:protocol> | serialization | serialization | string | 可選 | dubbo協議缺省爲hessian2,rmi協議缺省爲java,http協議缺省爲json | 性能調優 | 協議序列化方式,當協議支持多種序列化方式時使用,好比:dubbo協議的dubbo,hessian2,java,compactedjava,以及http協議的json等 | 2.0.5以上版本 |
<dubbo:protocol> | accesslog | accesslog | string/boolean | 可選 | 服務治理 | 設爲true,將向logger中輸出訪問日誌,也可填寫訪問日誌文件路徑,直接把訪問日誌輸出到指定文件 | 2.0.5以上版本 | |
<dubbo:protocol> | path | <path> | string | 可選 | 服務發現 | 提供者上下文路徑,爲服務path的前綴 | 2.0.5以上版本 | |
<dubbo:protocol> | transporter | transporter | string | 可選 | dubbo協議缺省爲netty | 性能調優 | 協議的服務端和客戶端實現類型,好比:dubbo協議的mina,netty等,能夠分拆爲server和client配置 | 2.0.5以上版本 |
<dubbo:protocol> | server | server | string | 可選 | dubbo協議缺省爲netty,http協議缺省爲servlet | 性能調優 | 協議的服務器端實現類型,好比:dubbo協議的mina,netty等,http協議的jetty,servlet等 | 2.0.5以上版本 |
<dubbo:protocol> | client | client | string | 可選 | dubbo協議缺省爲netty | 性能調優 | 協議的客戶端實現類型,好比:dubbo協議的mina,netty等 | 2.0.5以上版本 |
<dubbo:protocol> | dispatcher | dispatcher | string | 可選 | dubbo協議缺省爲all | 性能調優 | 協議的消息派發方式,用於指定線程模型,好比:dubbo協議的all, direct, message, execution, connection等 | 2.1.0以上版本 |
<dubbo:protocol> | queues | queues | int | 可選 | 0 | 性能調優 | 線程池隊列大小,當線程池滿時,排隊等待執行的隊列大小,建議不要設置,當線程程池時應當即失敗,重試其它服務提供機器,而不是排隊,除非有特殊需求。 | 2.0.5以上版本 |
<dubbo:protocol> | charset | charset | string | 可選 | UTF-8 | 性能調優 | 序列化編碼 | 2.0.5以上版本 |
<dubbo:protocol> | buffer | buffer | int | 可選 | 8192 | 性能調優 | 網絡讀寫緩衝區大小 | 2.0.5以上版本 |
<dubbo:protocol> | heartbeat | heartbeat | int | 可選 | 0 | 性能調優 | 心跳間隔,對於長鏈接,當物理層斷開時,好比拔網線,TCP的FIN消息來不及發送,對方收不到斷開事件,此時須要心跳來幫助檢查鏈接是否已斷開 | 2.0.10以上版本 |
<dubbo:protocol> | telnet | telnet | string | 可選 | 服務治理 | 所支持的telnet命令,多個命令用逗號分隔 | 2.0.5以上版本 | |
<dubbo:protocol> | register | register | boolean | 可選 | true | 服務治理 | 該協議的服務是否註冊到註冊中心 | 2.0.8以上版本 |
<dubbo:protocol> | contextpath | contextpath | String | 可選 | 缺省爲空串 | 服務治理 | 2.0.6以上版本 |
註冊中心配置:
配置類:com.alibaba.dubbo.config.RegistryConfig
說明:若是有多個不一樣的註冊中心,能夠聲明多個<dubbo:registry>標籤,並在<dubbo:service>或<dubbo:reference>的registry屬性指定使用的註冊中心。
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:registry> | id | string | 可選 | 配置關聯 | 註冊中心引用BeanId,能夠在<dubbo:service registry="">或<dubbo:reference registry="">中引用此ID | 1.0.16以上版本 | ||
<dubbo:registry> | address | <host:port> | string | 必填 | 服務發現 | 註冊中心服務器地址,若是地址沒有端口缺省爲9090,同一集羣內的多個地址用逗號分隔,如:ip:port,ip:port,不一樣集羣的註冊中心,請配置多個<dubbo:registry>標籤 | 1.0.16以上版本 | |
<dubbo:registry> | protocol | <protocol> | string | 可選 | dubbo | 服務發現 | 注同中心地址協議,支持dubbo, http, local三種協議,分別表示,dubbo地址,http地址,本地註冊中心 | 2.0.0以上版本 |
<dubbo:registry> | port | <port> | int | 可選 | 9090 | 服務發現 | 註冊中心缺省端口,當address沒有帶端口時使用此端口作爲缺省值 | 2.0.0以上版本 |
<dubbo:registry> | username | <username> | string | 可選 | 服務治理 | 登陸註冊中心用戶名,若是註冊中心不須要驗證可不填 | 2.0.0以上版本 | |
<dubbo:registry> | password | <password> | string | 可選 | 服務治理 | 登陸註冊中心密碼,若是註冊中心不須要驗證可不填 | 2.0.0以上版本 | |
<dubbo:registry> | transport | registry.transporter | string | 可選 | netty | 性能調優 | 網絡傳輸方式,可選mina,netty | 2.0.0以上版本 |
<dubbo:registry> | timeout | registry.timeout | int | 可選 | 5000 | 性能調優 | 註冊中心請求超時時間(毫秒) | 2.0.0以上版本 |
<dubbo:registry> | session | registry.session | int | 可選 | 60000 | 性能調優 | 註冊中心會話超時時間(毫秒),用於檢測提供者非正常斷線後的髒數據,好比用心跳檢測的實現,此時間就是心跳間隔,不一樣註冊中心實現不同。 | 2.1.0以上版本 |
<dubbo:registry> | file | registry.file | string | 可選 | 服務治理 | 使用文件緩存註冊中心地址列表及服務提供者列表,應用重啓時將基於此文件恢復,注意:兩個註冊中心不能使用同一文件存儲 | 2.0.0以上版本 | |
<dubbo:registry> | wait | registry.wait | int | 可選 | 0 | 性能調優 | 中止時等待通知完成時間(毫秒) | 2.0.0以上版本 |
<dubbo:registry> | check | check | boolean | 可選 | true | 服務治理 | 註冊中心不存在時,是否報錯 | 2.0.0以上版本 |
<dubbo:registry> | register | register | boolean | 可選 | true | 服務治理 | 是否向此註冊中心註冊服務,若是設爲false,將只訂閱,不註冊 | 2.0.5以上版本 |
<dubbo:registry> | subscribe | subscribe | boolean | 可選 | true | 服務治理 | 是否向此註冊中心訂閱服務,若是設爲false,將只註冊,不訂閱 | 2.0.5以上版本 |
<dubbo:registry> | dynamic | dynamic | boolean | 可選 | true | 服務治理 | 服務是否動態註冊,若是設爲false,註冊後將顯示後disable狀態,需人工啓用,而且服務提供者中止時,也不會自動取消冊,需人工禁用。 | 2.0.5以上版本 |
監控中心配置:
配置類:com.alibaba.dubbo.config.MonitorConfig
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:monitor> | protocol | protocol | string | 可選 | dubbo | 服務治理 | 監控中心協議,若是爲protocol="registry",表示從註冊中心發現監控中心地址,不然直連監控中心。 | 2.0.9以上版本 |
<dubbo:monitor> | address | <url> | string | 可選 | N/A | 服務治理 | 直連監控中心服務器地址,address="10.20.130.230:12080" | 1.0.16以上版本 |
應用信息配置:
配置類:com.alibaba.dubbo.config.ApplicationConfig
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:application> | name | application | string | 必填 | 服務治理 | 當前應用名稱,用於註冊中心計算應用間依賴關係,注意:消費者和提供者應用名不要同樣,此參數不是匹配條件,你當前項目叫什麼名字就填什麼,和提供者消費者角色無關,好比:kylin應用調用了morgan應用的服務,則kylin項目配成kylin,morgan項目配成morgan,可能kylin也提供其它服務給別人使用,但kylin項目永遠配成kylin,這樣註冊中心將顯示kylin依賴於morgan | 1.0.16以上版本 | |
<dubbo:application> | version | application.version | string | 可選 | 服務治理 | 當前應用的版本 | 2.2.0以上版本 | |
<dubbo:application> | owner | owner | string | 可選 | 服務治理 | 應用負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.0.5以上版本 | |
<dubbo:application> | organization | organization | string | 可選 | 服務治理 | 組織名稱(BU或部門),用於註冊中心區分服務來源,此配置項建議不要使用autoconfig,直接寫死在配置中,好比china,intl,itu,crm,asc,dw,aliexpress等 | 2.0.0以上版本 | |
<dubbo:application> | architecture | architecture | string | 可選 | 服務治理 | 用於服務分層對應的架構。如,intl、china。不一樣的架構使用不一樣的分層。 | 2.0.7以上版本 | |
<dubbo:application> | environment | environment | string | 可選 | 服務治理 | 應用環境,如:develop/test/product,不一樣環境使用不一樣的缺省值,以及做爲只用於開發測試功能的限制條件 | 2.0.0以上版本 | |
<dubbo:application> | compiler | compiler | string | 可選 | javassist | 性能優化 | Java字節碼編譯器,用於動態類的生成,可選:jdk或javassist | 2.1.0以上版本 |
<dubbo:application> | logger | logger | string | 可選 | slf4j | 性能優化 | 日誌輸出方式,可選:slf4j,jcl,log4j,jdk | 2.2.0以上版本 |
模塊信息配置:
配置類:com.alibaba.dubbo.config.ModuleConfig
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:module> | name | module | string | 必填 | 服務治理 | 當前模塊名稱,用於註冊中心計算模塊間依賴關係 | 2.2.0以上版本 | |
<dubbo:module> | version | module.version | string | 可選 | 服務治理 | 當前模塊的版本 | 2.2.0以上版本 | |
<dubbo:module> | owner | owner | string | 可選 | 服務治理 | 模塊負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.2.0以上版本 | |
<dubbo:module> | organization | organization | string | 可選 | 服務治理 | 組織名稱(BU或部門),用於註冊中心區分服務來源,此配置項建議不要使用autoconfig,直接寫死在配置中,好比china,intl,itu,crm,asc,dw,aliexpress等 | 2.2.0以上版本 |
服務提供者缺省值配置:
配置類:com.alibaba.dubbo.config.ProviderConfig
說明:該標籤爲<dubbo:service>和<dubbo:protocol>標籤的缺省值設置。
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:provider> | id | string | 可選 | dubbo | 配置關聯 | 協議BeanId,能夠在<dubbo:service proivder="">中引用此ID | 1.0.16以上版本 | |
<dubbo:provider> | protocol | <protocol> | string | 可選 | dubbo | 性能調優 | 協議名稱 | 1.0.16以上版本 |
<dubbo:provider> | host | <host> | string | 可選 | 自動查找本機IP | 服務發現 | 服務主機名,多網卡選擇或指定VIP及域名時使用,爲空則自動查找本機IP,建議不要配置,讓Dubbo自動獲取本機IP | 1.0.16以上版本 |
<dubbo:provider> | threads | threads | int | 可選 | 100 | 性能調優 | 服務線程池大小(固定大小) | 1.0.16以上版本 |
<dubbo:provider> | payload | payload | int | 可選 | 88388608(=8M) | 性能調優 | 請求及響應數據包大小限制,單位:字節 | 2.0.0以上版本 |
<dubbo:provider> | path | <path> | string | 可選 | 服務發現 | 提供者上下文路徑,爲服務path的前綴 | 2.0.0以上版本 | |
<dubbo:provider> | server | server | string | 可選 | dubbo協議缺省爲netty,http協議缺省爲servlet | 性能調優 | 協議的服務器端實現類型,好比:dubbo協議的mina,netty等,http協議的jetty,servlet等 | 2.0.0以上版本 |
<dubbo:provider> | client | client | string | 可選 | dubbo協議缺省爲netty | 性能調優 | 協議的客戶端實現類型,好比:dubbo協議的mina,netty等 | 2.0.0以上版本 |
<dubbo:provider> | codec | codec | string | 可選 | dubbo | 性能調優 | 協議編碼方式 | 2.0.0以上版本 |
<dubbo:provider> | serialization | serialization | string | 可選 | dubbo協議缺省爲hessian2,rmi協議缺省爲java,http協議缺省爲json | 性能調優 | 協議序列化方式,當協議支持多種序列化方式時使用,好比:dubbo協議的dubbo,hessian2,java,compactedjava,以及http協議的json,xml等 | 2.0.5以上版本 |
<dubbo:provider> | default | boolean | 可選 | false | 配置關聯 | 是否爲缺省協議,用於多協議 | 1.0.16以上版本 | |
<dubbo:provider> | filter | service.filter | string | 可選 | 性能調優 | 服務提供方遠程調用過程攔截器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 | |
<dubbo:provider> | listener | exporter.listener | string | 可選 | 性能調優 | 服務提供方導出服務監聽器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 | |
<dubbo:provider> | threadpool | threadpool | string | 可選 | fixed | 性能調優 | 線程池類型,可選:fixed/cached | 2.0.5以上版本 |
<dubbo:provider> | accepts | accepts | int | 可選 | 0 | 性能調優 | 服務提供者最大可接受鏈接數 | 2.0.5以上版本 |
<dubbo:provider> | version | version | string | 可選 | 0.0.0 | 服務發現 | 服務版本,建議使用兩位數字版本,如:1.0,一般在接口不兼容時版本號才須要升級 | 2.0.5以上版本 |
<dubbo:provider> | group | group | string | 可選 | 服務發現 | 服務分組,當一個接口有多個實現,能夠用分組區分 | 2.0.5以上版本 | |
<dubbo:provider> | delay | delay | int | 可選 | 0 | 性能調優 | 延遲註冊服務時間(毫秒)- ,設爲-1時,表示延遲到Spring容器初始化完成時暴露服務 | 2.0.5以上版本 |
<dubbo:provider> | timeout | default.timeout | int | 可選 | 1000 | 性能調優 | 遠程服務調用超時時間(毫秒) | 2.0.5以上版本 |
<dubbo:provider> | retries | default.retries | int | 可選 | 2 | 性能調優 | 遠程服務調用重試次數,不包括第一次調用,不須要重試請設爲0 | 2.0.5以上版本 |
<dubbo:provider> | connections | default.connections | int | 可選 | 0 | 性能調優 | 對每一個提供者的最大鏈接數,rmi、http、hessian等短鏈接協議表示限制鏈接數,dubbo等長鏈接協表示創建的長鏈接個數 | 2.0.5以上版本 |
<dubbo:provider> | loadbalance | default.loadbalance | string | 可選 | random | 性能調優 | 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用 | 2.0.5以上版本 |
<dubbo:provider> | async | default.async | boolean | 可選 | false | 性能調優 | 是否缺省異步執行,不可靠異步,只是忽略返回值,不阻塞執行線程 | 2.0.5以上版本 |
<dubbo:provider> | stub | stub | boolean | 可選 | false | 服務治理 | 設爲true,表示使用缺省代理類名,即:接口名 + Local後綴。 | 2.0.5以上版本 |
<dubbo:provider> | mock | mock | boolean | 可選 | false | 服務治理 | 設爲true,表示使用缺省Mock類名,即:接口名 + Mock後綴。 | 2.0.5以上版本 |
<dubbo:provider> | token | token | boolean | 可選 | false | 服務治理 | 令牌驗證,爲空表示不開啓,若是爲true,表示隨機生成動態令牌 | 2.0.5以上版本 |
<dubbo:provider> | registry | registry | string | 可選 | 缺省向全部registry註冊 | 配置關聯 | 向指定註冊中心註冊,在多個註冊中心時使用,值爲<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔,若是不想將該服務註冊到任何registry,可將值設爲N/A | 2.0.5以上版本 |
<dubbo:provider> | dynamic | dynamic | boolean | 可選 | true | 服務治理 | 服務是否動態註冊,若是設爲false,註冊後將顯示後disable狀態,需人工啓用,而且服務提供者中止時,也不會自動取消冊,需人工禁用。 | 2.0.5以上版本 |
<dubbo:provider> | accesslog | accesslog | string/boolean | 可選 | false | 服務治理 | 設爲true,將向logger中輸出訪問日誌,也可填寫訪問日誌文件路徑,直接把訪問日誌輸出到指定文件 | 2.0.5以上版本 |
<dubbo:provider> | owner | owner | string | 可選 | 服務治理 | 服務負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.0.5以上版本 | |
<dubbo:provider> | document | document | string | 可選 | 服務治理 | 服務文檔URL | 2.0.5以上版本 | |
<dubbo:provider> | weight | weight | int | 可選 | 性能調優 | 服務權重 | 2.0.5以上版本 | |
<dubbo:provider> | executes | executes | int | 可選 | 0 | 性能調優 | 服務提供者每服務每方法最大可並行執行請求數 | 2.0.5以上版本 |
<dubbo:provider> | actives | default.actives | int | 可選 | 0 | 性能調優 | 每服務消費者每服務每方法最大併發調用數 | 2.0.5以上版本 |
<dubbo:provider> | proxy | proxy | string | 可選 | javassist | 性能調優 | 生成動態代理方式,可選:jdk/javassist | 2.0.5以上版本 |
<dubbo:provider> | cluster | default.cluster | string | 可選 | failover | 性能調優 | 集羣方式,可選:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:provider> | deprecated | deprecated | boolean | 可選 | false | 服務治理 | 服務是否過期,若是設爲true,消費方引用時將打印服務過期警告error日誌 | 2.0.5以上版本 |
<dubbo:provider> | queues | queues | int | 可選 | 0 | 性能調優 | 線程池隊列大小,當線程池滿時,排隊等待執行的隊列大小,建議不要設置,當線程程池時應當即失敗,重試其它服務提供機器,而不是排隊,除非有特殊需求。 | 2.0.5以上版本 |
<dubbo:provider> | charset | charset | string | 可選 | UTF-8 | 性能調優 | 序列化編碼 | 2.0.5以上版本 |
<dubbo:provider> | buffer | buffer | int | 可選 | 8192 | 性能調優 | 網絡讀寫緩衝區大小 | 2.0.5以上版本 |
<dubbo:provider> | iothreads | iothreads | int | 可選 | CPU + 1 | 性能調優 | IO線程池,接收網絡讀寫中斷,以及序列化和反序列化,不處理業務,業務線程池參見threads配置,此線程池和CPU相關,不建議配置。 | 2.0.5以上版本 |
<dubbo:provider> | telnet | telnet | string | 可選 | 服務治理 | 所支持的telnet命令,多個命令用逗號分隔 | 2.0.5以上版本 | |
<dubbo:service> | contextpath | contextpath | String | 可選 | 缺省爲空串 | 服務治理 | 2.0.6以上版本 | |
<dubbo:provider> | layer | layer | string | 可選 | 服務治理 | 服務提供者所在的分層。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 |
服務消費者缺省值配置:
配置類:com.alibaba.dubbo.config.ConsumerConfig
說明:該標籤爲<dubbo:reference>標籤的缺省值設置。
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:consumer> | timeout | default.timeout | int | 可選 | 1000 | 性能調優 | 遠程服務調用超時時間(毫秒) | 1.0.16以上版本 |
<dubbo:consumer> | retries | default.retries | int | 可選 | 2 | 性能調優 | 遠程服務調用重試次數,不包括第一次調用,不須要重試請設爲0 | 1.0.16以上版本 |
<dubbo:consumer> | loadbalance | default.loadbalance | string | 可選 | random | 性能調優 | 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用 | 1.0.16以上版本 |
<dubbo:consumer> | async | default.async | boolean | 可選 | false | 性能調優 | 是否缺省異步執行,不可靠異步,只是忽略返回值,不阻塞執行線程 | 2.0.0以上版本 |
<dubbo:consumer> | connections | default.connections | int | 可選 | 100 | 性能調優 | 每一個服務對每一個提供者的最大鏈接數,rmi、http、hessian等短鏈接協議支持此配置,dubbo協議長鏈接不支持此配置 | 1.0.16以上版本 |
<dubbo:consumer> | generic | generic | boolean | 可選 | false | 服務治理 | 是否缺省泛化接口,若是爲泛化接口,將返回GenericService | 2.0.0以上版本 |
<dubbo:consumer> | check | check | boolean | 可選 | true | 服務治理 | 啓動時檢查提供者是否存在,true報錯,false忽略 | 1.0.16以上版本 |
<dubbo:consumer> | proxy | proxy | string | 可選 | javassist | 性能調優 | 生成動態代理方式,可選:jdk/javassist | 2.0.5以上版本 |
<dubbo:consumer> | owner | owner | string | 可選 | 服務治理 | 調用服務負責人,用於服務治理,請填寫負責人公司郵箱前綴 | 2.0.5以上版本 | |
<dubbo:consumer> | actives | default.actives | int | 可選 | 0 | 性能調優 | 每服務消費者每服務每方法最大併發調用數 | 2.0.5以上版本 |
<dubbo:consumer> | cluster | default.cluster | string | 可選 | failover | 性能調優 | 集羣方式,可選:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:consumer> | filter | reference.filter | string | 可選 | 性能調優 | 服務消費方遠程調用過程攔截器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 | |
<dubbo:consumer> | listener | invoker.listener | string | 可選 | 性能調優 | 服務消費方引用服務監聽器名稱,多個名稱用逗號分隔 | 2.0.5以上版本 | |
<dubbo:consumer> | registry | string | 可選 | 缺省向全部registry註冊 | 配置關聯 | 向指定註冊中心註冊,在多個註冊中心時使用,值爲<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔,若是不想將該服務註冊到任何registry,可將值設爲N/A | 2.0.5以上版本 | |
<dubbo:consumer> | layer | layer | string | 可選 | 服務治理 | 服務調用者所在的分層。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:consumer> | init | init | boolean | 可選 | false | 性能調優 | 是否在afterPropertiesSet()時飢餓初始化引用,不然等到有人注入或引用該實例時再初始化。 | 2.0.10以上版本 |
<dubbo:consumer> | cache | cache | string/boolean | 可選 | 服務治理 | 以調用參數爲key,緩存返回結果,可選:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:consumer> | validation | validation | boolean | 可選 | 服務治理 | 是否啓用JSR303標準註解驗證,若是啓用,將對方法參數上的註解進行校驗 | Dubbo2.1.0及其以上版本支持 |
方法級配置:
配置類:com.alibaba.dubbo.config.MethodConfig
說明:該標籤爲<dubbo:service>或<dubbo:reference>的子標籤,用於控制到方法級,
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:method> | name | string | 必填 | 標識 | 方法名 | 1.0.8以上版本 | ||
<dubbo:method> | timeout | <metodName>.timeout | int | 可選 | 缺省爲的timeout | 性能調優 | 方法調用超時時間(毫秒) | 1.0.8以上版本 |
<dubbo:method> | retries | <metodName>.retries | int | 可選 | 缺省爲<dubbo:reference>的retries | 性能調優 | 遠程服務調用重試次數,不包括第一次調用,不須要重試請設爲0 | 2.0.0以上版本 |
<dubbo:method> | loadbalance | <metodName>.loadbalance | string | 可選 | 缺省爲的loadbalance | 性能調優 | 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用 | 2.0.0以上版本 |
<dubbo:method> | async | <metodName>.async | boolean | 可選 | 缺省爲<dubbo:reference>的async | 性能調優 | 是否異步執行,不可靠異步,只是忽略返回值,不阻塞執行線程 | 1.0.9以上版本 |
<dubbo:method> | sent | <methodName>.sent | boolean | 可選 | true | 性能調優 | 異步調用時,標記sent=true時,表示網絡已發出數據 | 2.0.6以上版本 |
<dubbo:method> | actives | <metodName>.actives | int | 可選 | 0 | 性能調優 | 每服務消費者最大併發調用限制 | 2.0.5以上版本 |
<dubbo:method> | executes | <metodName>.executes | int | 可選 | 0 | 性能調優 | 每服務每方法最大使用線程數限制- -,此屬性只在<dubbo:method>做爲<dubbo:service>子標籤時有效 | 2.0.5以上版本 |
<dubbo:method> | deprecated | <methodName>.deprecated | boolean | 可選 | false | 服務治理 | 服務方法是否過期,此屬性只在<dubbo:method>做爲<dubbo:service>子標籤時有效 | 2.0.5以上版本 |
<dubbo:method> | sticky | <methodName>.sticky | boolean | 可選 | false | 服務治理 | 設置true 該接口上的全部方法使用同一個provider.若是須要更復雜的規則,請使用用路由 | 2.0.6以上版本 |
<dubbo:method> | return | <methodName>.return | boolean | 可選 | true | 性能調優 | 方法調用是否須要返回值,async設置爲true時才生效,若是設置爲true,則返回future,或回調onreturn等方法,若是設置爲false,則請求發送成功後直接返回Null | 2.0.6以上版本 |
<dubbo:method> | oninvoke | attribute屬性,不在URL中體現 | String | 可選 | 性能調優 | 方法執行前攔截 | 2.0.6以上版本 | |
<dubbo:method> | onreturn | attribute屬性,不在URL中體現 | String | 可選 | 性能調優 | 方法執行返回後攔截 | 2.0.6以上版本 | |
<dubbo:method> | onthrow | attribute屬性,不在URL中體現 | String | 可選 | 性能調優 | 方法執行有異常攔截 | 2.0.6以上版本 | |
<dubbo:method> | cache | <methodName>.cache | string/boolean | 可選 | 服務治理 | 以調用參數爲key,緩存返回結果,可選:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:method> | validation | <methodName>.validation | boolean | 可選 | 服務治理 | 是否啓用JSR303標準註解驗證,若是啓用,將對方法參數上的註解進行校驗 | Dubbo2.1.0及其以上版本支持 |
好比:
<
dubbo:reference
interface
=
"com.xxx.XxxService"
>
<
dubbo:method
name
=
"findXxx"
timeout
=
"3000"
retries
=
"2"
/>
</
dubbo:reference
>
|
方法參數配置:
配置類:com.alibaba.dubbo.config.ArgumentConfig
說明:該標籤爲<dubbo:method>的子標籤,用於方法參數的特徵描述,好比:
<
dubbo:method
name
=
"findXxx"
timeout
=
"3000"
retries
=
"2"
>
<
dubbo:argument
index
=
"0"
callback
=
"true"
/>
<
dubbo:method
>
|
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:argument> | index | int | 必填 | 標識 | 方法名 | 2.0.6以上版本 | ||
<dubbo:argument> | type | String | 與index二選一 | 標識 | 經過參數類型查找參數的index | 2.0.6以上版本 | ||
<dubbo:argument> | callback | <metodName><index>.retries | boolean | 可選 | 服務治理 | 參數是否爲callback接口,若是爲callback,服務提供方將生成反向代理,能夠從服務提供方反向調用消費方,一般用於事件推送. | 2.0.6以上版本 |
選項參數配置:
配置類:java.util.Map
說明:該標籤爲<dubbo:protocol>或<dubbo:service>或<dubbo:provider>或<dubbo:reference>或<dubbo:consumer>的子標籤,用於配置自定義參數,該配置項將做爲擴展點設置自定義參數使用。
標籤 | 屬性 | 對應URL參數 | 類型 | 是否必填 | 缺省值 | 做用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:parameter> | key | key | string | 必填 | 服務治理 | 路由參數鍵 | 2.0.0以上版本 | |
<dubbo:parameter> | value | value | string | 必填 | 服務治理 | 路由參數值 | 2.0.0以上版本 |
好比:
<
dubbo:protocol
name
=
"napoli"
>
<
dubbo:parameter
key
=
"http://10.20.160.198/wiki/display/dubbo/napoli.queue.name"
value
=
"xxx"
/>
</
dubbo:protocol
>
|
也能夠:
<
dubbo:protocol
name
=
"jms"
p:queue
=
"xxx"
/>
|
詳細參見:自定義參數
推薦使用Dubbo協議 |
Dubbo缺省協議採用單一長鏈接和NIO異步通信,適合於小數據量大併發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的狀況。 |
Dubbo缺省協議不適合傳送大數據量的服務,好比傳文件,傳視頻等,除非請求量很低。 |
<
dubbo:protocol
name
=
"dubbo"
port
=
"20880"
/>
|
Set default protocol:
<
dubbo:provider
protocol
=
"dubbo"
/>
|
Set service protocol:
<
dubbo:service
protocol
=
"dubbo"
/>
|
Multi port:
<
dubbo:protocol
id
=
"dubbo1"
name
=
"dubbo"
port
=
"20880"
/>
<
dubbo:protocol
id
=
"dubbo2"
name
=
"dubbo"
port
=
"20881"
/>
|
Dubbo protocol options:
<
dubbo:protocol
name=「dubbo」 port=「9090」 server=「netty」 client=「netty」 codec=「dubbo」 serialization=「hessian2」 charset=「UTF-8」 threadpool=「fixed」 threads=「100」 queues=「0」 iothreads=「9」 buffer=「8192」 accepts=「1000」 payload=「8388608」 />
|
Dubbo協議缺省每服務每提供者每消費者使用單一長鏈接,若是數據量較大,能夠使用多個鏈接。 |
<
dubbo:protocol
name
=
"dubbo"
connections
=
"2"
/>
|
爲防止被大量鏈接撐掛,可在服務提供方限制大接收鏈接數,以實現服務提供方自我保護。 |
<
dubbo:protocol
name
=
"dubbo"
accepts
=
"1000"
/>
|
缺省協議,使用基於mina1.1.7+hessian3.2.1的tbremoting交互。
爲何要消費者比提供者個數多:
因dubbo協議採用單一長鏈接,
假設網絡爲千兆網卡(1024Mbit=128MByte),
根據測試經驗數據每條鏈接最多隻能壓滿7MByte(不一樣的環境可能不同,供參考),
理論上1個服務提供者須要20個服務消費者才能壓滿網卡。
爲何不能傳大包:
因dubbo協議採用單一長鏈接,
若是每次請求的數據包大小爲500KByte,假設網絡爲千兆網卡(1024Mbit=128MByte),每條鏈接最大7MByte(不一樣的環境可能不同,供參考),
單個服務提供者的TPS(每秒處理事務數)最大爲:128MByte / 500KByte = 262。
單個消費者調用單個服務提供者的TPS(每秒處理事務數)最大爲:7MByte / 500KByte = 14。
若是能接受,能夠考慮使用,不然網絡將成爲瓶頸。
爲何採用異步單一長鏈接:
由於服務的現狀大都是服務提供者少,一般只有幾臺機器,
而服務的消費者多,可能整個網站都在訪問該服務,
好比Morgan的提供者只有6臺提供者,卻有上百臺消費者,天天有1.5億次調用,
若是採用常規的hessian服務,服務提供者很容易就被壓跨,
經過單一鏈接,保證單一消費者不會壓死提供者,
長鏈接,減小鏈接握手驗證等,
並使用異步IO,複用線程池,防止C10K問題。
(1) 約束:
數據通信 | 狀況 | 結果 |
---|---|---|
A->B | 類A多一種 屬性(或者說類B少一種 屬性) | 不拋異常,A多的那 個屬性的值,B沒有, 其餘正常 |
A->B | 枚舉A多一種 枚舉(或者說B少一種 枚舉),A使用多 出來的枚舉進行傳輸 | 拋異常 |
A->B | 枚舉A多一種 枚舉(或者說B少一種 枚舉),A不使用 多出來的枚舉進行傳輸 | 不拋異常,B正常接 收數據 |
A->B | A和B的屬性 名相同,但類型不相同 | 拋異常 |
A->B | serialId 不相同 | 正常傳輸 |
總結:會拋異常的狀況:枚 舉值一邊多一種,一邊少一種,正好使用了差異的那種,或者屬性名相同,類型不一樣
接口增長方法,對客戶端無影響,若是該方法不是客戶端須要的,客戶端不須要從新部署;
輸入參數和結果集中增長屬性,對客戶端無影響,若是客戶端並不須要新屬性,不用從新
部署;
輸入參數和結果集屬性名變化,對客戶端序列化無影響,可是若是客戶端不從新部署,無論輸入仍是輸出,屬性名變化的屬性值是獲取不到的。
總結:服務器端和客戶端對領域對象並不須要徹底一致,而是按照最大匹配原則。
(2) 配置:
dubbo.properties:
dubbo.service.protocol=dubbo
|
RMI協議採用JDK標準的java.rmi.*實現,採用阻塞式短鏈接和JDK標準序列化方式。 |
若是正在使用RMI提供服務給外部訪問(公司內網環境應該不會有攻擊風險),同時應用裏依賴了老的common-collections包(dubbo不會依賴這個包,請排查本身的應用有沒有使用)的狀況下,存在反序列化安全風險。 請檢查應用: 將commons-collections3 請升級到3.2.2版本:https://commons.apache.org/proper/commons-collections/release_3_2_2.html 將commons-collections4 請升級到4.1版本:https://commons.apache.org/proper/commons-collections/release_4_1.html 新版本的commons-collections解決了該問題 |
Define rmi protocol:
<
dubbo:protocol
name
=
"rmi"
port
=
"1099"
/>
|
Set default protocol:
<
dubbo:provider
protocol
=
"rmi"
/>
|
Set service protocol:
<
dubbo:service
protocol
=
"rmi"
/>
|
Multi port:
<
dubbo:protocol
id
=
"rmi1"
name
=
"rmi"
port
=
"1099"
/>
<
dubbo:protocol
id
=
"rmi2"
name
=
"rmi"
port
=
"2099"
/>
<
dubbo:service
protocol
=
"rmi1"
/>
|
Spring compatible:
<
dubbo:protocol
name
=
"rmi"
codec
=
"spring"
/>
|
Java標準的遠程調用協議。
(1) 約束:
(2) 配置:
dubbo.properties:
dubbo.service.protocol=rmi
|
(3) RMI配置:
java -Dsun.rmi.transport.tcp.responseTimeout=
3000
|
更多RMI優化參數請查看:
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes/guides/rmi/sunrmiproperties.html
Hessian協議用於集成Hessian的服務,Hessian底層採用Http通信,採用Servlet暴露服務,Dubbo缺省內嵌Jetty做爲服務器實現。 |
Hessian是Caucho開源的一個RPC框架:http://hessian.caucho.com,其通信效率高於WebService和Java自帶的序列化。 |
依賴:
<
dependency
>
<
groupId
>com.caucho</
groupId
>
<
artifactId
>hessian</
artifactId
>
<
version
>4.0.7</
version
>
</
dependency
>
|
能夠和原生Hessian服務互操做,即:
基於Hessian的遠程調用協議。
(1) 約束:
(2) 配置:
Define hessian protocol:
<
dubbo:protocol
name
=
"hessian"
port
=
"8080"
server
=
"jetty"
/>
|
Set default protocol:
<
dubbo:provider
protocol
=
"hessian"
/>
|
Set service protocol:
<
dubbo:service
protocol
=
"hessian"
/>
|
Multi port:
<
dubbo:protocol
id
=
"hessian1"
name
=
"hessian"
port
=
"8080"
/>
<
dubbo:protocol
id
=
"hessian2"
name
=
"hessian"
port
=
"8081"
/>
|
Directly provider:
<
dubbo:reference
id
=
"helloService"
interface
=
"HelloWorld"
url
=
"hessian://10.20.153.10:8080/helloWorld"
/>
|
<
dubbo:protocol
...
server
=
"jetty"
/>
|
<
dubbo:protocol
...
server
=
"servlet"
/>
|
web.xml:
<
servlet
>
<
servlet-name
>dubbo</
servlet-name
>
<
servlet-class
>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</
servlet-class
>
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>dubbo</
servlet-name
>
<
url-pattern
>/*</
url-pattern
>
</
servlet-mapping
>
|
注意,若是使用servlet派發請求:
採用Spring的HttpInvoker實現 |
2.3.0以上版本支持 |
基於http表單的遠程調用協議。參見:[HTTP協議使用說明]
(1) 約束:
(2) 配置:
dubbo.xml:
<dubbo:protocol name=
"http"
port=
"8080"
/>
|
<
dubbo:protocol
...
server
=
"jetty"
/>
|
<
dubbo:protocol
...
server
=
"servlet"
/>
|
web.xml:
<
servlet
>
<
servlet-name
>dubbo</
servlet-name
>
<
servlet-class
>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</
servlet-class
>
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>dubbo</
servlet-name
>
<
url-pattern
>/*</
url-pattern
>
</
servlet-mapping
>
|
注意,若是使用servlet派發請求:
2.3.0以上版本支持。 |
基於CXF的frontend-simple和transports-http實現。 |
CXF是Apache開源的一個RPC框架:http://cxf.apache.org,由Xfire和Celtix合併而來 。 |
依賴:
<
dependency
>
<
groupId
>org.apache.cxf</
groupId
>
<
artifactId
>cxf-rt-frontend-simple</
artifactId
>
<
version
>2.6.1</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.apache.cxf</
groupId
>
<
artifactId
>cxf-rt-transports-http</
artifactId
>
<
version
>2.6.1</
version
>
</
dependency
>
|
能夠和原生WebService服務互操做,即:
基於WebService的遠程調用協議。
(1) 約束:
(2) 配置:
Define hessian protocol:
<
dubbo:protocol
name
=
"webservice"
port
=
"8080"
server
=
"jetty"
/>
|
Set default protocol:
<
dubbo:provider
protocol
=
"webservice"
/>
|
Set service protocol:
<
dubbo:service
protocol
=
"webservice"
/>
|
Multi port:
<
dubbo:protocol
id
=
"webservice1"
name
=
"webservice"
port
=
"8080"
/>
<
dubbo:protocol
id
=
"webservice2"
name
=
"webservice"
port
=
"8081"
/>
|
Directly provider:
<
dubbo:reference
id
=
"helloService"
interface
=
"HelloWorld"
url
=
"webservice://10.20.153.10:8080/com.foo.HelloWorld"
/>
|
WSDL:
<
dubbo:protocol
...
server
=
"jetty"
/>
|
<
dubbo:protocol
...
server
=
"servlet"
/>
|
web.xml:
<
servlet
>
<
servlet-name
>dubbo</
servlet-name
>
<
servlet-class
>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</
servlet-class
>
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>dubbo</
servlet-name
>
<
url-pattern
>/*</
url-pattern
>
</
servlet-mapping
>
|
注意,若是使用servlet派發請求:
2.3.0以上版本支持。 |
Thrift說明 Thrift是Facebook捐給Apache的一個RPC框架,參見:http://thrift.apache.org |
dubbo thrift協議 當前 dubbo 支持的 thrift 協議是對 thrift 原生協議的擴展,在原生協議的基礎上添加了一些額外的頭信息,好比service name,magic number等。使用dubbo thrift協議一樣須要使用thrift的idl compiler編譯生成相應的java代碼,後續版本中會在這方面作一些加強。 |
依賴:
<
dependency
>
<
groupId
>org.apache.thrift</
groupId
>
<
artifactId
>libthrift</
artifactId
>
<
version
>0.8.0</
version
>
</
dependency
>
|
全部服務共用一個端口:(與原生Thrift不兼容)
<dubbo:protocol name=
"thrift"
port=
"3030"
/>
|
Thrift不支持數據類型:
2.3.0以上版本支持。 |
Memcached說明 Memcached是一個高效的KV緩存服務器,參見:http://memcached.org/ |
能夠經過腳本或監控中心手工填寫表單註冊memcached服務的地址:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"memcached://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash"
));
|
而後在客戶端使用時,不須要感知Memcached的地址:
<
dubbo:reference
id
=
"cache"
interface
=
"http://10.20.160.198/wiki/display/dubbo/java.util.Map"
group
=
"member"
/>
|
或者,點對點直連:
<
dubbo:reference
id
=
"cache"
interface
=
"http://10.20.160.198/wiki/display/dubbo/java.util.Map"
url
=
"memcached://10.20.153.10:11211"
/>
|
也能夠使用自定義接口:
<
dubbo:reference
id
=
"cache"
interface
=
"com.foo.CacheService"
url
=
"memcached://10.20.153.10:11211"
/>
|
方法名建議和memcached的標準方法名相同,即:get(key), set(key, value), delete(key)。
若是方法名和memcached的標準方法名不相同,則須要配置映射關係:(其中"p:xxx"爲spring的標準p標籤)
<
dubbo:reference
id
=
"cache"
interface
=
"com.foo.CacheService"
url
=
"memcached://10.20.153.10:11211"
p:set
=
"putFoo"
p:get
=
"getFoo"
p:delete
=
"removeFoo"
/>
|
2.3.0以上版本支持。 |
Redis說明 Redis是一個高效的KV存儲服務器,參見:http://redis.io |
能夠經過腳本或監控中心手工填寫表單註冊redis服務的地址:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.
class
).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf(
"zookeeper://10.20.153.10:2181"
));
registry.register(URL.valueOf(
"redis://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash"
));
|
而後在客戶端使用時,不須要感知Redis的地址:
<
dubbo:reference
id
=
"store"
interface
=
"http://10.20.160.198/wiki/display/dubbo/java.util.Map"
group
=
"member"
/>
|
或者,點對點直連:
<
dubbo:reference
id
=
"store"
interface
=
"http://10.20.160.198/wiki/display/dubbo/java.util.Map"
url
=
"redis://10.20.153.10:6379"
/>
|
也能夠使用自定義接口:
<
dubbo:reference
id
=
"store"
interface
=
"com.foo.StoreService"
url
=
"redis://10.20.153.10:6379"
/>
|
方法名建議和redis的標準方法名相同,即:get(key), set(key, value), delete(key)。
若是方法名和redis的標準方法名不相同,則須要配置映射關係:(其中"p:xxx"爲spring的標準p標籤)
<
dubbo:reference
id
=
"cache"
interface
=
"com.foo.CacheService"
url
=
"memcached://10.20.153.10:11211"
p:set
=
"putFoo"
p:get
=
"getFoo"
p:delete
=
"removeFoo"
/>
|
推薦使用Zookeeper註冊中心 |
不須要啓動任何中心節點,只要廣播地址同樣,就能夠互相發現 |
組播受網絡結構限制,只適合小規模應用或開發階段使用。 |
組播地址段: 224.0.0.0 - 239.255.255.255 |
<
dubbo:registry
address
=
"multicast://224.5.6.7:1234"
/>
|
Or:
<
dubbo:registry
protocol
=
"multicast"
address
=
"224.5.6.7:1234"
/>
|
爲了減小廣播量,Dubbo缺省使用單播發送提供者地址信息給消費者,
若是一個機器上同時啓了多個消費者進程,消費者需聲明unicast=false,不然只會有一個消費者能收到消息:
<
dubbo:registry
address
=
"multicast://224.5.6.7:1234?unicast=false"
/>
|
Or:
<
dubbo:registry
protocol
=
"multicast"
address
=
"224.5.6.7:1234"
>
<
dubbo:parameter
key
=
"unicast"
value
=
"false"
/>
</
dubbo:registry
>
|
建議使用dubbo-2.3.3以上版本的zookeeper註冊中心客戶端 |
Zookeeper說明 Zookeeper是Apacahe Hadoop的子項目,是一個樹型的目錄服務,支持變動推送,適合做爲Dubbo服務的註冊中心,工業強度較高,可用於生產環境,並推薦使用,參見:http://zookeeper.apache.org |
Zookeeper安裝 安裝方式參見: Zookeeper安裝手冊,只需搭一個原生的Zookeeper服務器,並將Quick Start中Provider和Consumer裏的conf/dubbo.properties中的dubbo.registry.addrss的值改成zookeeper://127.0.0.1:2181便可使用 |
可靠性聲明 阿里內部並無採用Zookeeper作爲註冊中心,而是使用本身實現的基於數據庫的註冊中心,即:Zookeeper註冊中心並無在阿里內部長時間運行的可靠性保障,此Zookeeper橋接實現只爲開源版本提供,其可靠性依賴於Zookeeper自己的可靠性。 |
兼容性聲明 因2.0.8最初設計的zookeeper存儲結構不能擴充不一樣類型的數據,2.0.9版本作了調整,因此不兼容,需所有改用2.0.9版本才行,之後的版本會保持兼容2.0.9。 2.2.0版本改成基於zkclient實現,需增長zkclient的依賴包,2.3.0版本增長了基於curator的實現,做爲可選實現策略。 |
流程說明:
支持如下功能:
在provider和consumer中增長zookeeper客戶端jar包依賴:
<
dependency
>
<
groupId
>org.apache.zookeeper</
groupId
>
<
artifactId
>zookeeper</
artifactId
>
<
version
>3.3.3</
version
>
</
dependency
>
|
或直接下載:http://repo1.maven.org/maven2/org/apache/zookeeper/zookeeper
支持zkclient和curator兩種Zookeeper客戶端實現:
從2.2.0版本開始缺省爲zkclient實現,以提高zookeeper客戶端的健狀性。
ZKClient是Datameer開源的一個Zookeeper客戶端實現,開源比較早,參見:https://github.com/sgroschupf/zkclient |
缺省配置:
<
dubbo:registry
...
client
=
"zkclient"
/>
|
或:
dubbo.registry.client=zkclient
|
或:
zookeeper://10.20.153.10:2181?client=zkclient
|
需依賴:
<
dependency
>
<
groupId
>com.github.sgroschupf</
groupId
>
<
artifactId
>zkclient</
artifactId
>
<
version
>0.1</
version
>
</
dependency
>
|
或直接下載:http://repo1.maven.org/maven2/com/github/sgroschupf/zkclient
從2.3.0版本開始支持可選curator實現。
Curator是Netflix開源的一個Zookeeper客戶端實現,比較活躍,參見:https://github.com/Netflix/curator |
若是須要改成curator實現,請配置:
<
dubbo:registry
...
client
=
"curator"
/>
|
或:
dubbo.registry.client=curator
|
或:
zookeeper://10.20.153.10:2181?client=curator
|
需依賴:
<
dependency
>
<
groupId
>com.netflix.curator</
groupId
>
<
artifactId
>curator-framework</
artifactId
>
<
version
>1.1.10</
version
>
</
dependency
>
|
或直接下載:http://repo1.maven.org/maven2/com/netflix/curator/curator-framework
Zookeeper單機配置:
<
dubbo:registry
address
=
"zookeeper://10.20.153.10:2181"
/>
|
Or:
<
dubbo:registry
protocol
=
"zookeeper"
address
=
"10.20.153.10:2181"
/>
|
Zookeeper集羣配置:
<
dubbo:registry
address
=
"zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181"
/>
|
Or:
<
dubbo:registry
protocol
=
"zookeeper"
address
=
"10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181"
/>
|
同一Zookeeper,分紅多組註冊中心:
<
dubbo:registry
id
=
"chinaRegistry"
protocol
=
"zookeeper"
address
=
"10.20.153.10:2181"
group
=
"china"
/>
<
dubbo:registry
id
=
"intlRegistry"
protocol
=
"zookeeper"
address
=
"10.20.153.10:2181"
group
=
"intl"
/>
|
Redis說明 Redis是一個高效的KV存儲服務器,參見:http://redis.io |
Redis安裝 安裝方式參見: Redis安裝手冊,只需搭一個原生的Redis服務器,並將Quick Start中Provider和Consumer裏的conf/dubbo.properties中的dubbo.registry.addrss的值改成redis://127.0.0.1:6379便可使用 |
Redis過時數據 經過心跳的方式檢測髒數據,服務器時間必須相同,而且對服務器有必定壓力。 |
可靠性聲明 阿里內部並無採用Redis作爲註冊中心,而是使用本身實現的基於數據庫的註冊中心,即:Redis註冊中心並無在阿里內部長時間運行的可靠性保障,此Redis橋接實現只爲開源版本提供,其可靠性依賴於Redis自己的可靠性。 |
從2.1.0版本開始支持 |
數據結構:
調用過程:
選項:
Config redis registry:
<
dubbo:registry
address
=
"redis://10.20.153.10:6379"
/>
|
Or:
<
dubbo:registry
address
=
"redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379"
/>
|
Or:
<
dubbo:registry
protocol
=
"redis"
address
=
"10.20.153.10:6379"
/>
|
Or:
<
dubbo:registry
protocol
=
"redis"
address
=
"10.20.153.10:6379,10.20.153.11:6379,10.20.153.12:6379"
/>
|
Dogfooding 註冊中心自己就是一個普通的Dubbo服務,能夠減小第三方依賴,使總體通信方式一致。 |
適用性說明 此SimpleRegistryService只是簡單實現,不支持集羣,可做爲自定義註冊中心的參考,但不適合直接用於生產環境。 |
Export simple registry service:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<!-- 當前應用信息配置 -->
<
dubbo:application
name
=
"simple-registry"
/>
<!-- 暴露服務協議配置 -->
<
dubbo:protocol
port
=
"9090"
/>
<!-- 暴露服務配置 -->
<
dubbo:service
interface
=
"com.alibaba.dubbo.registry.RegistryService"
ref
=
"registryService"
registry
=
"N/A"
ondisconnect
=
"disconnect"
callbacks
=
"1000"
>
<
dubbo:method
name
=
"subscribe"
><
dubbo:argument
index
=
"1"
callback
=
"true"
/></
dubbo:method
>
<
dubbo:method
name
=
"unsubscribe"
><
dubbo:argument
index
=
"1"
callback
=
"false"
/></
dubbo:method
>
</
dubbo:service
>
<!-- 簡單註冊中心實現,可自行擴展實現集羣和狀態同步 -->
<
bean
id
=
"registryService"
class
=
"com.alibaba.dubbo.registry.simple.SimpleRegistryService"
/>
</
beans
>
|
Reference the simple registry service:
<
dubbo:registry
address
=
"127.0.0.1:9090"
/>
|
Or:
<
dubbo:service
interface
=
"com.alibaba.dubbo.registry.RegistryService"
group
=
"simple"
version
=
"1.0.0"
... >
|
<
dubbo:registry
address
=
"127.0.0.1:9090"
group
=
"simple"
version
=
"1.0.0"
/>
|
監控中心也是一個標準的Dubbo服務,能夠經過註冊中心發現,也能夠直連。 |
1.1 暴露一個簡單監控中心服務到註冊中心: (若是是用安裝包,不須要本身寫這個配置,若是是本身實現監控中心,則須要)
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<!-- 當前應用信息配置 -->
<
dubbo:application
name
=
"simple-monitor"
/>
<!-- 鏈接註冊中心配置 -->
<
dubbo:registry
address
=
"127.0.0.1:9090"
/>
<!-- 暴露服務協議配置 -->
<
dubbo:protocol
port
=
"7070"
/>
<!-- 暴露服務配置 -->
<
dubbo:service
interface
=
"com.alibaba.dubbo.monitor.MonitorService"
ref
=
"monitorService"
/>
<
bean
id
=
"monitorService"
class
=
"com.alibaba.dubbo.monitor.simple.SimpleMonitorService"
/>
</
beans
>
|
1.2 經過註冊中心發現監控中心服務:
<
dubbo:monitor
protocol
=
"registry"
/>
|
或:
dubbo.monitor.protocol=registry
|
2.1 暴露一個簡單監控中心服務,但不註冊到註冊中心: (若是是用安裝包,不須要本身寫這個配置,若是是本身實現監控中心,則須要)
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
>
<!-- 當前應用信息配置 -->
<
dubbo:application
name
=
"simple-monitor"
/>
<!-- 暴露服務協議配置 -->
<
dubbo:protocol
port
=
"7070"
/>
<!-- 暴露服務配置 -->
<
dubbo:service
interface
=
"com.alibaba.dubbo.monitor.MonitorService"
ref
=
"monitorService"
registry
=
"N/A"
/>
<
bean
id
=
"monitorService"
class
=
"com.alibaba.dubbo.monitor.simple.SimpleMonitorService"
/>
</
beans
>
|
2.2 直連監控中心服務:
<
dubbo:monitor
address
=
"dubbo://127.0.0.1:7070/com.alibaba.dubbo.monitor.MonitorService"
/>
|
或:
<
dubbo:monitor
address
=
"127.0.0.1:7070"
/>
|
或:
dubbo.monitor.address=
127.0
.
0.1
:
7070
|
Dubbo2.0.5以上版本服務提供端口支持telnet命令,
使用如:
telnet localhost 20880
或者:
echo status | nc -i 1 localhost 20880
telnet命令能夠擴展,參見:擴展參考手冊第6條。
status命令所檢查的資源也能夠擴展,參見:擴展參考手冊第5條。
(list services and methods)
ls
顯示服務列表。
ls -l
顯示服務詳細信息列表。
ls XxxService
顯示服務的方法列表。
ls -l XxxService
顯示服務的方法詳細信息列表。
(print server ports and connections)
ps
顯示服務端口列表。
ps -l
顯示服務地址列表。
ps 20880
顯示端口上的鏈接信息。
ps -l 20880
顯示端口上的鏈接詳細信息。
(change default service)
cd XxxService
改變缺省服務,當設置了缺省服務,凡是須要輸入服務名做爲參數的命令,均可以省略服務參數。
cd /
取消缺省服務。
(print working default service)
pwd
顯示當前缺省服務。
trace XxxService
跟蹤1次服務任意方法的調用狀況。
trace XxxService 10
跟蹤10次服務任意方法的調用狀況。
trace XxxService xxxMethod
跟蹤1次服務方法的調用狀況
trace XxxService xxxMethod 10
跟蹤10次服務方法的調用狀況。
count XxxService
統計1次服務任意方法的調用狀況。
count XxxService 10
統計10次服務任意方法的調用狀況。
count XxxService xxxMethod
統計1次服務方法的調用狀況。
count XxxService xxxMethod 10
統計10次服務方法的調用狀況。
invoke XxxService.xxxMethod({"prop": "value"})
調用服務的方法。
invoke xxxMethod({"prop": "value"})
調用服務的方法(自動查找包含此方法的服務)。
status
顯示彙總狀態,該狀態將彙總全部資源的狀態,當所有OK時則顯示OK,只要有一個ERROR則顯示ERROR,只要有一個WARN則顯示WARN。
status -l
顯示狀態列表。
2.0.6以上版本支持
log debug
修改dubbo logger的日誌級別
log 100
查看file logger的最後100字符的日誌
help
顯示telnet命幫助信息。
help xxx
顯示xxx命令的詳細幫助信息。
clear
清除屏幕上的內容。
clear 100
清除屏幕上的指定行數的內容。
exit
退出當前telnet命令行。
mvn dubbo:registry
以缺省的9090端口啓動一個簡易註冊中心
mvn dubbo:registry -Dport=9099
以指定的9099端口啓動一個簡易註冊中心
(還沒有發佈)
mvn dubbo:create
生成demo服務提供者應用
mvn dubbo:create -Dapplication=xxx -Dpackage=com.alibaba.xxx -Dservice=XxxService,YyyService -Dversion=1.0.0
生成指定接口和版本的服務提供者應用
緣由以下:
Provider上儘可能多配置Consumer端的屬性,讓Provider實現者一開始就思考Provider服務特色、服務質量的問題。
示例:
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
timeout
=
"300"
retry
=
"2"
loadbalance
=
"random"
actives
=
"0"
/>
<
dubbo:service
interface
=
"com.alibaba.hello.api.WorldService"
version
=
"1.0.0"
ref
=
"helloService"
timeout
=
"300"
retry
=
"2"
loadbalance
=
"random"
actives
=
"0"
>
<
dubbo:method
name
=
"findAllPerson"
timeout
=
"10000"
retries
=
"9"
loadbalance
=
"leastactive"
actives
=
"5"
/>
<
dubbo:service
/>
|
在Provider能夠配置的Consumer端屬性有:
詳細配置說明參見:Dubbo配置參考手冊
<
dubbo:protocol
threads
=
"200"
/>
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
executes
=
"200"
>
<
dubbo:method
name
=
"findAllPerson"
executes
=
"50"
/>
</
dubbo:service
>
|
Provider上能夠配置的Provider端屬性有:
目前有負責人信息和組織信息(用於區分站點)。
有問題時便於的找到服務的負責人,至少寫兩我的以便備份。
負責人和組織的信息能夠在註冊中心的上看到。
示例:
<
dubbo:application
owner=」ding.lid,william.liangf」 organization=」intl」 />
|
<
dubbo:service
owner=」ding.lid,william.liangf」 />
|
<
dubbo:reference
owner=」ding.lid,william.liangf」 />
|
dubbo:service、dubbo:reference沒有配置負責人,則使用dubbo:application設置的負責人。
配置方法以下:
<
dubbo:registry
file=」${user.home}/output/dubbo.cache」 />
|
注意:
這個文件會緩存:
有了這項配置後,當應用重啓過程當中,Dubbo註冊中心不可用時則應用會從這個緩存文件讀取服務提供者列表的信息,進一步保證應用可靠性。
這樣在註冊中心推送有延遲的狀況下,消費者經過緩存列表也能調用到原地址,保證調用成功。
Dragoon監控服務在註冊中心上的狀態:http://dubbo-reg1.hst.xyi.cn.alidc.net:8080/status/com.alibaba.morgan.member.MemberService:1.0.5,確保註冊中心上有該服務的存在。
監控服務提供者端口狀態:echo status | nc --i 1 20880 | grep OK | wc --l,其中的20880爲服務端口
如 assertEqauls(「OK」, ((EchoService)memberService).$echo(「OK」));
Dubbo2中全部的配置項均可以Spring配置中,而且能夠針對單個服務配置。
# 如徹底不配置使用Dubbo缺省值,參見Dubbo配置參考手冊中的說明。
在Dubbo1中須要在dubbo.properties文件中的配置項,Dubbo2中配置示例以下:
<dubbo:application name=
"myalibaba"
>
|
對應dubbo.properties中的Key名dubbo.application.name
<dubbo:registry address=
"11.22.33.44:9090"
>
|
對應dubbo.properties中的Key名dubbo.registry.address
能夠在多個配置項設置超時,由上至下覆蓋(即上面的優先),示例以下:
# 其它的參數(retries、loadbalance、actives等)的覆蓋策略也同樣。
提供者端特定方法的配置
<dubbo:service
interface
=
"com.alibaba.xxx.XxxService"
>
<dubbo:method name=
"findPerson"
timeout=
"1000"
/>
</dubbo:service>
|
提供者端特定接口的配置
<dubbo:service
interface
=
"com.alibaba.xxx.XxxService"
timeout=
"200"
/>
|
# timeout能夠在多處設置,配置項及覆蓋規則詳見: Dubbo配置參考手冊
全局配置項值,對應dubbo.properties中的Key名dubbo.service.invoke.timeout
<dubbo:protocol name=
"dubbo"
port=
"20880"
/>
|
對應dubbo.properties中的Key名dubbo.service.protocol、dubbo.service.server.port
<dubbo:protocol threads=
"100"
/>
|
對應dubbo.properties中的Key名dubbo.service.max.thread.threads.size
<dubbo:reference
interface
=
"com.alibaba.xxx.XxxService"
check=
"false"
/>
|
對應dubbo.properties中的Key名alibaba.intl.commons.dubbo.service.allow.no.provider
如下數據供參考:
1、新建一個benchmark工程,如demo.benchmark
2、導入本身服務的接口api包和dubbo.benchmark.jar(解壓dubbo.benchmark.tar.gz,在lib目錄下)
3、新建一個類,實現AbstractClientRunnable
a、實現父類的構造函數
b、實現invoke方法,經過serviceFactory建立本地接口代理,並實現本身的業務邏輯,以下
public
Object invoke(ServiceFactory serviceFactory) {
DemoService demoService = (DemoService) serviceFactory.get(DemoService.
class
);
return
demoService.sendRequest(
"hello"
);
}
|
4、將本身的benchmark工程打成jar包,如demo.benchmark.jar
5、將demo.benchmark.jar 和服務的api包放到dubbo.benchmark/lib目錄下
6、配置duubo.properties
7、運行run.bat(windows)或run.sh(linux)
如想測試dubbo的不一樣版本,直接替換lib下的dubbo的jar包便可。
a、本次性能測試,測試了dubbo2.0全部支持的協議在不一樣大小和數據類型下的表現,並與dubbo1.0進行了對比。
b、總體性能相比1.0有了提高,平均提高10%,使用dubbo2.0新增的dubbo序列化還能得到10%~50%的性能提高,詳見下面的性能數據。
c、穩定性測試中因爲將底層通訊框架從mina換成netty,old區對象的增加大大減小,50小時運行,增加不到200m,無fullgc。(能夠確認爲mina在高併發下的設計缺陷)
d、存在的問題:在50k數據的時候2.0性能不如1.0,懷疑多是緩衝區設置的問題,下版本會進一步確認。
主機/ip
硬件配置
操做系統及參數調整
10.20.153.11 | 機型 | Tecal BH620 | |
CPU | model name : Intel(R) Xeon(R) CPU E5520 @ 2.27GHz cache size : 8192 KB processor_count : 16 | ||
內存 | Total System Memory: 6G Hardware Memory Info: Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown | ||
網絡 | Total System Memory: 6G Hardware Memory Info: Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown | ||
磁盤 | /dev/sda: 597.9 GB, | 2.6.18-128.el5xen x86_64 | |
10.20.153.10 | 機型 | Tecal BH620 | |
CPU | model name : Intel(R) Xeon(R) CPU E5520 @ 2.27GHz cache size : 8192 KB processor_count : 16 | ||
內存 | Total System Memory: 6G Hardware Memory Info: Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown Size: 4096MB, 1066MHz(0.9ns) Size: NoModule, Unknown | ||
網絡 | eth0: Link is up at 1000 Mbps, full duplex. peth0: Link is up at 1000 Mbps, full duplex. | ||
磁盤 | /dev/sda: 597.9 GB, | 2.6.18-128.el5xen x86_64 |
主機/ip
軟件名稱及版本
關鍵參數
java version "1.6.0_18" Java(TM) SE Runtime Environment (build 1.6.0_18-b07) Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode) | -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 | |
jboss-4.0.5.GA | ||
httpd-2.0.61 | KeepAlive On MaxKeepAliveRequests 100000 KeepAliveTimeout 180 MaxRequestsPerChild 1000000 <IfModule worker.c> StartServers 5 MaxClients 1024 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 64 ThreadLimit 128 ServerLimit 16 </IfModule> |
場景名稱
對應指標名稱
指望值範圍
實際值
是否知足指望(是/否)
1k數據 | 響應時間 | 0.9ms | 0.79ms | 是 |
1k數據 | TPS | 10000 | 11994 | 是 |
2.0性能不低於1.0,2.0和1.0互調用的性能無明顯降低。 除了50k string其他皆經過
JVM內存運行穩定,無OOM,堆內存中無不合理的大對象的佔用。經過
CPU、內存、網絡、磁盤、文件句柄佔用平穩。經過
無頻繁線程鎖,線程數平穩。經過
業務線程負載均衡。經過
一、性能測試場景(10併發)
a、傳入1kString,不作任何處理,原樣返回
b、傳入50kString,不作任何處理,原樣返回
c、傳入200kString,不作任何處理,原樣返回
d、傳入1k pojo(嵌套的複雜person對象),不作任何處理,原樣返回
上述場景在dubbo1.0\dubbo2.0(hessian2序列化)\dubbo2.0(dubbo序列化)\rmi\hessian3.2.0\http(json序列化)進行10分鐘的性能測試。 主要考察序列化和網絡IO的性能,所以服務端無任何業務邏輯。取10併發是考慮到http協議在高併發下對CPU的使用率較高可能會先打到瓶頸。
二、併發場景(20併發)
傳入1kString,在服務器段循環1w次,每次從新生成一個隨機數而後進行拼裝。
考察業務線程是否可以分配到每一個CPU上。
三、穩定性場景(20併發)
同時調用1個參數爲String(5k)方法,1個參數爲person對象的方法,1個參數爲map(值爲3個person)的方法,持續運行50小時。
四、高壓力場景(20併發)
在穩定性場景的基礎上,將提供者和消費者佈置成均爲2臺(一臺機器2個實例),且String的參數從20byte到200k,每隔10分鐘隨機變換。
TPS成功平均值 | 響應時間成功平均值(ms) | |
dubbo1 (hessian2序列化+mina) |
10813.5 | 0.9 |
dubbo2 (hessian2序列化+netty) |
11994 | 0.79 |
dubbo2 (dubbo序列化+netty) |
13620 | 0.67 |
rmi | 2461.79 | 4 |
hessian | 2417.7 | 4.1 |
http(json序列化) | 8179.08 | 1.15 |
2.0和1.0默認 對比百分比 |
10.92 | -12.22 |
dubbo序列化相比hessian2序列化百分比 | 13.56 | -15.19 |
TPS成功平均值 | 響應時間成功平均值(ms) | |
dubbo1 (hessian2序列化+mina) |
11940 | 0.8 |
dubbo2 (hessian2序列化+netty) |
14402 | 0.64 |
dubbo2 (dubbo序列化+netty) |
15096 | 0.6 |
rmi | 11136.02 | 0.81 |
hessian | 11426.83 | 0.79 |
http(json序列化) | 8919.27 | 1.04 |
2.0和1.0默認 對比百分比 |
20.62 | -20.00 |
dubbo序列化相比hessian2序列化百分比 | 4.82 | -6.25 |
TPS成功平均值 | 響應時間成功平均值(ms) | |
dubbo1 (hessian2序列化+mina) |
1962.7 | 5.1 |
dubbo2 (hessian2序列化+netty) |
1293 | 5.03 |
dubbo2 (dubbo序列化+netty) |
1966 | 7.68 |
rmi | 3349.88 | 2.9 |
hessian | 1925.33 | 5.13 |
http(json序列化) | 3247.1 | 3 |
2.0和1.0默認 對比百分比 |
-34.12 | -1.37 |
dubbo序列化相比hessian2序列化百分比 | 52.05 | 52.68 |
TPS成功平均值 | 響應時間成功平均值(ms) | |
dubbo1 (hessian2序列化+mina) |
324.2 | 30.8 |
dubbo2 (hessian2序列化+netty) |
362.92 | 27.49 |
dubbo2 (dubbo序列化+netty) |
569.5 | 17.51 |
rmi | 1031.28 | 9.61 |
hessian | 628.06 | 15.83 |
http(json序列化) | 1011.97 | 9.79 |
2.0和1.0默認 對比百分比 |
11.94 | -10.75 |
dubbo序列化相比hessian2序列化百分比 | 56.92 | -36.30 |
Dubbo2.0的性能測試結論爲經過,從性能、內存佔用和穩定性上都有了提升和改進。由其是內存管理因爲將mina換成netty,大大減小了1.0版本在高併發大數據下的內存大鋸齒。以下圖:
Dubbo2.0相比較Dubbo1.0(默認使用的都是hessian2序列化)性能均有提高(除了50k String),詳見第五章的性能數據。
出於兼容性考慮默認的序列化方式和1.0保持一導致用hessian2,如對性能有更高要求能夠使用dubbo序列化,由其是在處理複雜對象時,在大數據量下能得到50%的提高(但此時已不建議使用Dubbo協議)。
Dubbo的設計目的是爲了知足高併發小數據量的rpc調用,在大數據量下的性能表現並很差,建議使用rmi或http協議。
本次性能測試考察的是dubbo自己的性能,實際使用過程當中的性能有待應用來驗證。
因爲dubbo自己的性能佔用都在毫秒級,佔的基數很小,性能提高可能對應用總體的性能變化不大。
因爲郵件篇幅所限沒有列出全部的監控圖,如需得到可在大力神平臺上查詢。
統計於 2012-02-03 (2.0.12)