本文背景還要從網易考拉海購(下文簡稱“考拉”)微服務化說起,現在任何大型的互聯網應用,尤其是電商應用從Monolithic單體應用走向微服務化已經是必然趨勢。微服務化是一個比較寬泛的概念,涉及到一個產品生命周期的多個方面,首先它作為一個指導原則指引業務劃分、架構解耦等;技術層面實施微服務需要開發測試階段、運行階段、發布階段、部署階段等一系列基礎框架的支撐。我們在享受服務化易擴展易部署等便利性的同時,也面臨新的問題,如數據一致性、分布式調用鏈路追蹤、異常定位、日志采集等。
本文將集中在支撐微服務交互、運行的基礎框架講解上,即考拉當前使用的Dubbok框架,Dubbok由阿里開源Dubbo框架的優化和功能改進而來。當前開源上可選用的微服務框架主要有Dubbo、Spring Cloud等,鑒于Dubbo完備的功能和文檔且在國內被眾多大型互聯網公司選用,考拉自然也選擇了Dubbo作為服務化的基礎框架。其實相比于Dubbo,Spring Cloud可以說是一個更完備的微服務解決方案,它從功能性上是Dubbo的一個超集,個人認為從選型上對于一些中小型企業Spring Cloud可能是一個更好的選擇。提起Spring Cloud,一些開發的第一印象是http+JSON的rest通信,性能上難堪重用,其實這也是一種誤讀。微服務選型要評估以下幾點:內部是否存在異構系統集成的問題;備選框架功能特性是否滿足需求;http協議的通信對于應用的負載量會否真正成為瓶頸點(Spring Cloud也并不是和http+JSON強制綁定的,如有必要Thrift、protobuf等高效的RPC、序列化協議同樣可以作為替代方案);社區活躍度、團隊技術儲備等。作為已經沒有團隊持續維護的開源項目,選擇Dubbo框架內部就必須要組建一個維護團隊,先不論你要準備要集成多少功能做多少改造,作為一個支撐所有工程正常運轉的基礎組件,問題的及時響應與解答、重大缺陷的及時修復能力就已足夠重要。
下文將選取Dubbo高性能RPC通信原理、服務注冊發現特性、依賴隔離、啟動與停機等幾個方面闡述Dubbok的工作原理和相關改進工作。
一、高性能RPC
Dubbo作為一個分布式通信框架,最基本的職責就是完成跨進程的遠程調用(RPC)。以下是RPC基本流程圖:
RPC基本原理非常簡單,那么Dubbo是如何實現高效的RPC通信的呢,和其他分布式通信組件關注點一樣,主要集中在以下幾點的優化:
1.協議棧:
Dubbo支持自定義RPC協議,冗余字段少、通信性能高;
序列化協議支持hessian2、Dubbo自定義序列化等高性能協議;
Dubbo支持序列化協議解碼在業務線程(Netty3編碼自動在業務線程執行);
Dubbo RPC通信協議棧
2.線程模型:
依賴Netty3的非阻塞線程模型,支持I/O、業務邏輯線程分離,通過Handler鏈處理請求。
Netty基本線程模型
Dubbo業務線程與netty3 IO線程交互
這里特別強調Netty3,是因為Netty4在線程模型、buffer緩沖區等方面做了重大的設計和性能改進,包括Inbound、Outbound事件強制在I/O線程發起、buffer通過緩沖池減少分配釋放、DirectBuffer實現緩沖區零復制等。Netty這塊升級相對是一個高風險的點,明面上的API兼容性改造是小,如對Netty4工作原理認識不足,新的線程模型、buffer緩沖池等帶來的非預期性能下降、內存泄露等問題相對更難定位與跟蹤。
講到線程模型,實現上密切相關的Dubbo網絡連接模型必須要提一下。Dubbo默認是所有服務共享單一的TCP長連接的(這也是為什么服務接口不適合傳輸大負載值,即容易阻塞其他服務的調用)。為響應慢或重要的服務接口考慮,Dubbo支持設置多TCP連接,此時連接數和線程池數默認是綁定的,即每連接對應一個線池,consumer、provider都執行這個策略,從線程隔離的角度講是合理的,但不注意也容易造成線程占用資源過多,尤其是對于消費端基本無線程阻塞的情況下可能是一個設計缺陷。
3.緩沖區:
Dubbo默認使用的全部是heap緩沖區,因此Socket通信不可避免會存在內核緩沖區和堆緩沖區復制消耗;除此之外在RPC協議解析(包括粘包/半包處理)、序列化協議解析等處理上也存在heap區內的復制,因此性能上是存在優化點的(當然要確有必要)。
二、自動注冊/發現、負載均衡等服務化特性
高性能通信是Dubbo作為RPC框架的基本功能,但使其區別于Thrift、hessian、gRPC等框架的關鍵在于其新增的服務間自動協調、服務治理等特性。
1. 服務自動注冊自動發現、負載均衡
服務自動注冊發現依賴于注冊中心的支持,consumer與provider通過注冊中心獲取各自地址后直接通信。目前考拉使用Zookeeper作為注冊中心,Dubbo原生支持Redis作為注冊中心,使用pub/sub機制協調服務的上下線事件通知,但Redis方案要求服務器時間同步且存在性能消耗過大的缺點。

消費者/提供者注冊中心交互圖
使用Zookeeper作為注冊中心,建議選用curator作為客戶端框架;
Zookeeper服務器異常宕機并重新啟動的場景下,Dubbo服務的recover恢復機制存在不能重新注冊的問題,導致老zk session失效后服務被錯誤清除。
服務框架常見負載均衡實現方案包括:集中式、分布式,分布式又可分進程內、分進程兩種。Dubbo采用的是服務發現和負載均衡共同集成在consumer端的分布式進程內解決方案
Dubbo負載均衡策略
負載均衡策略上Dubbo原生提供的有基于權重隨機負載、最少活躍數優先、Roundrobin、一致性Hash等幾個方案。
在實際應用中,為了能對個別錯誤率較高的異常provider做到及時發現、及時引流,Dubbok增加了新的負載均衡策略,在支持權重的基礎上自動發現異常provider,異常期自動減流、正常后自動恢復流量。
2.路由、集群容錯、限流
和負載均衡策略一樣,Dubbo的路由方案是集成在消費端的,加上集群容錯功能客戶端相對是一個重量的功能封裝?蛇x方案是將路由工作移到注冊中心完成(這要求注冊中心具有較強的可定制性,不僅路由像權限控制、服務過濾、環境隔離等都可由注冊中心集成)
限流目前支持consumer、provider端并發限流,實際上是基于信號量限制的,以接口粒度分配信號量,當信號量用完新的調用將被拒絕,當業務返回后信號量被釋放。
消費端限流應該是為整個提供端集群分配信號量,而Dubbo錯誤的將信號量分配給單個機器。這個問題目前可以通過下文提到的隔離框架的流控功能來實現。
限流并非精確限制,不應當依賴其實現嚴格的并發數控制。
后端backend服務限流需要業務方合理評估每個接口的流控值,要求對業務量有足夠經驗值(可能要在多次線上調優后才能最終得出合理的流控值)?祭瓋炔苛骺貙嵺`證明,對于保證服務穩定性、優先保證重要消費方、實現服務隔離等有著重要的作用。
3.服務動態治理
動態治理本質上是依賴Dubbo運行期參數的動態調整,再通用一點其實就是應用的參數動態調整,開源常用的disconf、diamond、archaius等集中配置管理工具都是設計來解決這個問題。Dubbo內部在url參數傳遞模型基礎上實現了一套參數動態配置邏輯,個人認為相比于Dubbo的實現,集成disconf等更專業的框架應該是更好的解決方案,或許Dubbo為了一些其他設計目標解除了對一些外部框架的強制依賴。動態治理可以實現從基本參數如timeout、mock到一些高級特性如路由、限流等幾乎所有的運行期參數調整。
Dubbo原生在動態配置上存在很多bug,配置不生效或配置規則誤讀等問題都遇到過,如果你再使用原生Dubbo過程中也遇到任何配置問題,Dubbok應該都已經解決掉了。
三、依賴隔離(服務降級)
當應用被設計依賴外部服務時,要始終保持警惕狀態:外部依賴是不穩定的,為此對接外部依賴做好解耦是關鍵,避免外部接口發生異常拖垮自身系統。Dubbo提供了超時timeout機制作為最基本的解耦措施,同時在接口報錯時支持提供降級的容錯邏輯;除了容錯降級,Dubbo進一步支持強制的短路降級。
容錯 短路
然而在容錯降級與短路降級之間,Dubbo缺乏一種在容錯與短路間切換的機制,即自動熔斷。自動熔斷要達到的效果是:當接口偶然報錯時執行容錯返回備用數據,而當接口持續大量報錯時能自動在消費端對接口調用短路直接返回備用數據,之后持續監測接口可用性,接口恢復后自動恢復調用。這樣能最大限度減少接口異常對消費方的影響,同時也減輕本就處于異常狀態的提供端負載。
自動熔斷工作原理圖
Dubbok通過標準SPI的的形式,實現了熔斷功能。目前支持兩套方案:一套是自己實現的熔斷邏輯;一套是通過集成hystrix框架實現。目前支持錯誤率、最低請求量、熔斷時間窗等基本配置,支持將業務異常納入統計范疇;以上參數均可通過
SOA治理平臺運行期動態調整;支持外部Dubbo依賴調用的準實時監控。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://www.vmgcyvh.cn/
本文標題:網易考拉海購Dubbok框架優化詳解
本文網址:http://www.vmgcyvh.cn/html/support/11121520450.html