來自官網http://dubbo.apache.org/zh-cn/docs/user/preface/requirements.html
以上是 Dubbo 最基本的幾個需求
在大規模服務化之前,應用可能只是通過 RMI 或 Hessian 等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過 F5 等硬件進行負載均衡。
當服務越來越多時,服務 URL 配置管理變得非常困難,F5 硬件負載均衡器的單點壓力也越來越大。 此時需要一個服務註冊中心,動態地註冊和發現服務,使服務的位置透明。並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和 Failover,降低對 F5 硬件負載均衡器的依賴,也能減少部分成本。
當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啓動,架構師都不能完整的描述應用的架構關係。 這時,需要自動畫出應用間的依賴關係圖,以幫助架構師理清關係。
接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器? 爲了解決這些問題,第一步,要將服務現在每天的調用量,響應時間,都統計出來,作爲容量規劃的參考指標。其次,要可以動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程中記錄響應時間的變化,直到響應時間到達閾值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。
Dubbo架構
節點角色說明
節點 | 角色說明 |
---|---|
Provider |
暴露服務的服務提供方 |
Consumer |
調用遠程服務的服務消費方 |
Registry |
服務註冊與發現的註冊中心 |
Monitor |
統計服務的調用次數和調用時間的監控中心 |
Container |
服務運行容器 |
調用關係說明
- 服務容器負責啓動,加載,運行服務提供者。
- 服務提供者在啓動時,向註冊中心註冊自己提供的服務。
- 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
- 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
- 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
- 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
Dubbo 架構具有以下幾個特點,分別是連通性、健壯性、伸縮性、以及向未來架構的升級性。
升級性
當服務集羣規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分佈式服務架構不會帶來阻力。下圖是未來可能的一種架構:
節點角色說明
節點 | 角色說明 |
---|---|
Deployer |
自動部署服務的本地代理 |
Repository |
倉庫用於存儲服務應用發佈包 |
Scheduler |
調度中心基於訪問壓力自動增減服務提供者 |
Admin |
統一管理控制檯 |
Registry |
服務註冊與發現的註冊中心 |
Monitor |
統計服務的調用次數和調用時間的監控中心 |
本地服務 Spring 配置
local.xml:
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>
遠程服務 Spring 配置
在本地服務的基礎上,只需做簡單配置,即可完成遠程化:
- 將上面的
local.xml
配置拆分成兩份,將服務定義部分放在服務提供方remote-provider.xml
,將服務引用部分放在服務消費方remote-consumer.xml
。 - 並在提供方增加暴露服務配置
<dubbo:service>
,在消費方增加引用服務配置<dubbo:reference>
。
remote-provider.xml:
<!-- 和本地服務一樣實現遠程服務 -->
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<!-- 增加暴露遠程服務配置 -->
<dubbo:service interface=“com.xxx.XxxService” ref=“xxxService” />
remote-consumer.xml:
<!-- 增加引用遠程服務配置 -->
<dubbo:reference id=“xxxService” interface=“com.xxx.XxxService” />
<!-- 和本地服務一樣使用遠程服務 -->
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>
成熟度
功能成熟度
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 |
容量規劃
以下數據供參考:
使用 Dubbo 的會員服務項目
- 每天接收 4 億次遠程調用
- 使用 12 臺網站標配機器提供服務(8 核 CPU,8G 內存)
- 平均負載在 1 以下(對於 8 核 CPU 負載很低)
- 平均響應時間 2.3 到 2.5 毫秒,網絡開銷約佔 1.5 到 1.6 毫秒(和數據包大小有關)
使用 Dubbo 的產品授權服務項目
- 每天接收 3 億次遠程調用
- 使用 8 臺網站標配機器提供服務(8 核CPU,8G 內存)
- 平均負載在 1 以下(對於 8 核 CPU 負載很低)
- 平均響應時間 1.4 到 2.8 毫秒,網絡開銷約佔 1.0 到 1.1 毫秒(和數據包大小有關)
測試分析
性能分析評估
Dubbo 2.0 的性能測試結論爲通過,從性能、內存佔用和穩定性上都有了提高和改進。由其是內存管理由於將 mina 換成netty,大大減少了 1.0 版本在高併發大數據下的內存大鋸齒。
測試侷限性分析(可選)
本次性能測試考察的是 dubbo 本身的性能,實際使用過程中的性能有待應用來驗證。
由於 dubbo 本身的性能佔用都在毫秒級,佔的基數很小,性能提升可能對應用整體的性能變化不大。
由於郵件篇幅所限沒有列出所有的監控圖,如需獲得可在大力神平臺上查詢。
API編程接口
- 註解
註解 | 說明 |
---|---|
@Reference | 消費端服務引用註解 |
@Service | 提供端服務暴露註解 |
@EnableDubbo | |
其他常用Spring註解API |
- 編程API
API | 說明 |
---|---|
ReferenceConfig | Service配置採集和引用編程接口 |
ServiceConfig | Service配置採集和暴露編程接口 |
ApplicationConfig | Application配置採集API |
RegistryConfig | 註冊中心配置採集API |
ConsumerConfig | 消費端默認配置採集API |
ProviderConfig | 提供端默認配置採集API |
ProtocolConfig | RPC協議配置採集API |
ArcumentConfig | 服務參數級配置採集API |
MethodConfig | 服務方法級配置採集API |
ModuleConfig | 服務治理Module配置採集API |
MonitorConfig | 監控配置採集API |
RpcContext | 編程上下文API |
SPI擴展
如果公司內部有維護的自定義SPI擴展庫,在業務工程升級到2.7.0之前,請務必先確保擴展庫與2.7.0的兼容性。如果發現有兼容性問題,請通過修改包名引用的方式完成升級,並重新打包。
SPI擴展點 | 說明 |
---|---|
Registry | 包括RegistryFactory , Registry ,RegistryService 等擴展點 |
Protocol | RPC協議擴展 |
Serialization | 序列化協議擴展 |
Cluster | 集羣容錯策略擴展,如Failover, Failfast等 |
Loadbalance | 負載均衡策略擴展 |
Transporter | 傳輸框架擴展,如Netty等 |
Monitor | 監控中心擴展,包括MonitorFactory, Monitor, MonitorService等 |
Router | 路由規則擴展 |
Filter | 攔截器擴展 |
應用調用架構