服務化實戰之 dubbo、dubbox、motan、thrift、grpc等RPC架構比較及選型_服務化

來源:互聯網
上載者:User
概述

前段時間項目要做服務化,所以我比較了現在流行的幾大RPC架構的優缺點以及使用情境,最終結合本身項目的實際情況選擇了使用dubbox作為rpc基礎服務架構。下面就簡單介紹一下RPC架構技術選型的過程。 RPC簡述

該系列文章將講述以下RPC架構的helloword執行個體以及其實現原理簡述,由於每一種RPC架構的原理實現不同且都比較複雜,如果想深入研究還請自行到官網或者其他技術部落格學習。
RPC架構職責
RPC架構要向調用方屏蔽各種複雜性,要向服務提供者也屏蔽各類複雜性: 調用方感覺就像調用本地函數一樣 服務提供者感覺就像實現一個本地函數一樣來實現服務

RPC架構是架構(微)服務化的首要基礎組件,它能大大降低架構微服務化的成本,提高調用方與服務提供者的研發效率,屏蔽跨進程調用函數(服務)的各類複雜細節
RPC架構的職責是:讓調用方感覺就像調用本地函數一樣調用遠端函數、讓服務提供者感覺就像實現一個本地函數一樣來實現服務

對於不是很理解服務化的同學可以看看這兩篇文章:
服務化架構的演化與實踐
淺談服務化架構

服務化的好處
互連網架構為什麼要做服務化。 服務架構的拆分原則

來源:李林峰的文章:華為內部如何實施微服務架構。基本就靠這5大原則

服務拆分原則:圍繞業務功能進行垂直和水平分割。大小粒度是痛點,也是團隊爭論的焦點。 不好的實踐 以代碼量作為衡量標準,例如500行以內。 拆分的粒度越小越好,例如以單個資源的操作粒度為劃分原則。 建議的原則 功能完整性、職責單一性。 粒度適中,團隊可接受。 迭代演化,非一蹴而就。 API的版本相容性優先考慮。

代碼量多少不能作為衡量微服務劃分是否合理的原則,因為我們知道同樣一個服務,功能本身的複雜性不同,代碼量也不同。還有一點需要重點強調,在項目剛開始的時候,不要期望微服務的劃分一蹴而就。
微服務架構的演化,應該是一個循序漸進的過程。在一個公司、一個項目組,它也需要一個循序漸進的演化過程。一開始劃不好,沒有關係。當演化到一個階段時,微服務的部署、測試和營運等成本都非常低的時候,這對於你的團隊來說就是一個好的微服務。 服務架構的開發原則

微服務的開發還會面臨依賴滯後的問題。例如:A要做一個社會安全號碼碼校正,依賴服務提供者B。由於B把社會安全號碼碼校正服務的開發優先順序排的比較低,無法滿足A的交付時間點。A會面臨要麼等待,要麼自己實現一個社會安全號碼碼校正功能。

以前單體架構的時候,大家需要什麼,往往喜歡自己寫什麼,這其實是沒有太嚴重的依賴問題。但是到了微服務時代,微服務是一個團隊或者一個小組提供的,這個時候一定沒有辦法在某一個時刻同時把所有的服務都提供出來,“需求實現滯後”是必然存在的。

一個好的實踐策略就是介面先行,語言中立,服務提供者和消費者解耦,並行開發,提升產能。無論有多少個服務,首先需要把介面識別和定義出來,然後雙方基於介面進行契約驅動開發,利用Mock服務提供者和消費者,互相解耦,並行開發,實現依賴解耦。

採用契約驅動開發,如果需求不穩定或者經常變化,就會面臨一個介面契約頻繁變更的問題。對於服務提供者,不能因為擔心介面變更而遲遲不對外提供介面,對於消費者要擁抱變更,而不是抱怨和抵觸。要解決這個問題,一種比較好的實踐就是管理 + 技術雙管齊下: 允許介面變更,但是對變更的頻度要做嚴格管控。 提供全線上的API文檔服務(例如Swagger UI),將離線的API文檔轉成全線上、互動式的API文檔服務。 API變更的主動通知機制,要讓所有消費該API的消費者能夠及時感知到API的變更。 契約驅動測試,用於對相容性做迴歸測試。 服務架構的測試原則

微服務開發完成之後需要對其進行測試。微服務的測試包括單元測試、介面測試、整合測試和行為測試等,其中最重要的就是契約測試:

利用微服務架構提供的Mock機制,可以分別產生類比消費者的用戶端測試樁和提供者的服務端測試樁,雙方可以基於Mock測試樁對微服務的介面契約進行測試,雙方都不需要等待對方功能代碼開發完成,實現了並行開發與測試,提高了微服務的構建效率。基於介面的契約測試還能快速的發現不相容的介面變更,例如修改欄位類型、刪除欄位等。 服務架構的部署原則

測試完成之後,需要對微服務進行自動化部署。微服務的部署原則:獨立部署和生命週期管理、基礎設施自動化。需要有一套類似於CI/CD的流水線來做基礎設施自動化,具體可以參考Netflix開源的微服務持續傳遞流水線Spinnaker:

最後一起看下微服務的運行容器:微部署可以部署在Dorker容器、PaaS平台(VM)或者物理機上。使用Docker部署微服務會帶來很多優先: 一致的環境,線上線下環境一致。 避免對特定雲基礎設施供應商的依賴。 降低營運團隊負擔。 高效能接近裸機效能。 多租戶。

相比於傳統的物理機部署,微服務可以由PaaS平台實現微服務自動化部署和生命週期管理。除了部署和營運自動化,微服務雲化之後還可以充分享受到更靈活的資源調度: 雲的彈性和敏捷。 雲的動態性和資源隔離。 服務架構的治理原則

服務部署上線之後,最重要的工作就是服務治理。微服務治理原則:線上治理、即時動態生效。
微服務常用的治理策略: 流量控制:動態、靜態流量控制。 服務降級。 逾時控制。 優先順序調度。 流量遷移。 調用鏈跟蹤和分析。 服務路由。 服務上線審批、下線通知。 SLA策略控制。 微服務治理模型如下所示:

最上層是為服務治理的UI介面,提供線上、配置化的治理介面供營運人員使用。SDK層是提供了微服務治理的各種介面,供服務治理Portal調用。最下面的就是被治理的微服務叢集,叢集各節點會監聽服務治理的操作去做即時重新整理。例如:修改了流控閾值之後,服務治理服務會把新的流控的閾值刷到服務註冊中心,服務提供者和消費者監聽到閾值變更之後,擷取新的閾值並重新整理到記憶體中,實現即時生效。由於目前服務治理策略資料量不是特別大,所以可以將服務治理的資料放到服務註冊中心(例如etcd/ZooKeeper),沒有必要再單獨做一套。 服務最佳實務

介紹完微服務實施之後,下面我們一起學習下微服務的最佳實務。
服務路由:本地短路策略。關鍵技術點:優先調用本JVM內部服務提供者,其次是相同主機或者VM的,最後是跨網路調用。通過本地短路,可以避免遠程調用的網路開銷,降低服務調用時延、提升成功率。原理如下所示:


服務調用方式:同步調用、非同步呼叫、並行調用。一次服務調用,通常就意味著會掛一個服務調用線程。採用非同步呼叫,可以避免線程阻塞,提升系統的輸送量和可靠性。但是在實際項目中非同步呼叫也有一些缺點,導致使用不是特別廣泛:
需要寫非同步回調邏輯,與傳統的介面調用使用方式不一致,開發難度大一些。
一些情境下需要緩衝上下文資訊,引入可靠性問題。
並行調用適用於多個服務調用沒有上下文依賴,邏輯上可以平行處理,類似JDK的Fork/Join, 並行服務調用涉及到同步轉非同步、非同步轉同步、結果匯聚等,技術實現難度較大,目前很多服務架構並不支援。採用並行服務調用,可以把傳統串列的服務調用最佳化成平行處理,能夠極大的縮短服務調用時延。

微服務故障隔離:線程級、進程級、容器級、VM級、物理機級等。關鍵技術點: 支援服務部署到不同線程/線程池中。 核心服務和非核心服務隔離部署。 為了防止線程膨脹,支援共用和獨佔兩種線程池策略。

談到分布式,就繞不開事務一致性問題:大部分業務可以通過最終一致性來解決,極少部分需要採用強一致性。

具體的策略如下: 最終一致性,可以基於訊息中介軟體實現。 強一致性,使用TCC架構。服務架構本身不會直接提供“分散式交易”,往往根據實際需要遷入分散式交易架構來支援分散式交易。

微服務的效能三要素: I/O模型,這個通常會選用非堵塞的,Java裡面可能用java原生的。 線程調度模型。 序列化方式。

公司內部服務化,對效能要求較高的情境,建議使用非同步非阻塞I/O(Netty) + 二進位序列化(Thrift壓縮二進位等) + Reactor線程調度模型。

最後我們一起看下微服務的介面相容性原則:技術保證、管理協同。 制定並嚴格執行《微服務前向相容性規範》,避免發生不相容修改或者私自修改不通知周邊的情況。 介面相容性技術保證:例如Thrift的IDL,支援新增、修改和刪除欄位、欄位定義位置無關性,碼流支援亂序等。 持續傳遞流水線的每日構建和契約化驅動測試,能夠快速識別和發現不相容。 現在流行的RPC架構: 服務治理型 dubbo dubbox motan 多語言型 grpc thrift avro Protocol Buffers (google)

上圖來自於dubbo。服務治理型RPC架構結構大多如此,大致分為服務提供者,服務消費者,註冊中心,監控警示中心幾大模組。 服務效能

在服務化,或者微服務化過程中,首先考慮的問題就是效能問題,因為在服務化之後,會增加以下額外的效能開銷: 用戶端需要對訊息進行序列化,主要佔用CPU計算資源。 序列化時需要建立位元組,耗費JVM堆記憶體或者堆外記憶體。 用戶端需要將序列化之後的位元組發送給服務端,佔用網路頻寬資源。 服務端讀取到碼流之後,需要將請求資料報還原序列化成請求對象,佔用CPU計算資源。 服務端通過反射的方式調用服務提供者實作類別,反射本身對效能影響就比較大。 服務端將響應結果序列化,佔用CPU計算資源。 服務端將應答碼流發送給用戶端,佔用網路頻寬資源。 用戶端讀取應答碼流,還原序列化成響應訊息,佔用CPU資源。 RPC架構高效能設計

要想提高效率,除了硬體的提升,主要考慮以下三個方面: I/O調度模型:同步阻塞I/O(BIO)還是非阻塞I/O(NIO)。 序列化架構的選擇:文本協議、二進位協議或壓縮二進位協議。 線程調度模型:串列調度還是並行調度,鎖競爭還是無鎖化演算法。

IO調度現在主流的就是netty。
高效能序列化目前效能最好的是ice,google 的 pb協議,FB的thrift協議等
線程沒啥好說的,肯定多線程了。當然也可以是AKKA(java) 總結

綜上所述,服務化是現在大型互連網公司主流的架構模式,現在還有更流行的微服務,docker部署等等。

個人建議採用dubbox,整合其他各種協議,在該系列文章最後有各個協議的效能對比。

之所以建議採用dubbox是因為,dubbox有比價完善的服務治理模型,其包含ZK註冊中心,服務監控等,可以很方便的為我們服務。
雖然dubbo本身不支援多語言,但是我們可以整合其他的序列化協議,比如thrift、avro,使其可以支援多種入門語言,讓部門間的協作溝通更加靈活方便

當然,在實際使用過程中,尤其是整合其他協議的過程中,肯定需要對協議本身有比較深入的瞭解,才能正確的使用。 motan

新浪微博開源的RPC架構

helloword樣本直接去官網下載運行即可

github地址:https://github.com/weibocom/motan
文檔地址:https://github.com/weibocom/motan/wiki/zh_quickstart
使用者指南;https://github.com/weibocom/motan/wiki/zh_userguide

# grpc

中文版官方文檔:gRPC 官方文檔中文版

helloWord樣本,我就是根據這個文章做的,寫得挺詳細的:rpc架構之gRPC 學習 - hello world

grpc原理: grpc原理分析 dubbo

dubbo 已經與12年年底停止維護升級,忽略 thrift

請參考我寫的另一篇文章:thrift學習筆記(一) thrift簡介及第一個helloword程式 dubbox

dubbox 是噹噹團隊基於dubbo升級的一個版本。是一個分布式的服務架構,可直接用於生產環境作為SOA服務架構。
dubbo官網首頁:http://dubbo.io/ 上面有詳細的使用者指南和官方文檔,介紹的比較詳細,這裡不再贅述。

噹噹官方的github地址:https://github.com/dangdangdotcom/dubbox

升級為spring4.X(及其他相依元件)版本dubbox的github的地
址:https://github.com/yjmyzz/dubbox。

參考資料【部落格:菩提樹下的楊過 的文章寫得非常全面,介紹的已經非常詳細了】:
dubbox升級spring到4.x及添加log4j2支援
分布式服務架構 dubbo/dubbox 入門樣本
dubbox 的各種管理和監管
dubbo/dubbox 增加原生thrift及avro支援

# 各個RPC架構效能比較 測試環境

jdk7
win7 64位
idea
個人筆記本配置:

person對象:

private int age;private String name;private boolean sex;private int childrenCount;

測試資料,入參:

private int ageStart;private int ageEnd;

傳回值:

Person.PersonBuilder builder = Person.builder();List<Person> list = new ArrayList<Person>();for (short i = 0; i < 10; i++) {    list.add(builder.age(i).childrenCount(i).name("test" + i).sex(true).build());}return list;
各協議測試使用的配置 grpc


rpc getPersonList (yjmyzz.grpc.study.dto.QueryParameter) returns (yjmyzz.grpc.study.dto.PersonList) {} motan

<motan:basicService export="demoMotan:8002"
group="motan-demo-rpc" accessLog="false" shareChannel="true" module="motan-demo-rpc"
application="myMotanDemo" registry="registry" id="serviceBasicConfig"/> dubbox

<dubbo:protocol name="dubbo" serialization="kryo" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/><dubbo:service interface="com.alibaba.dubbo.demo.person.PersonService" ref="personService" protocol="dubbo"/>
thrift

TNonblockingServer + TFramedTransport 測試結果

rgpc 100000 次NettyServer調用,耗時:53102毫秒,平均1883次/秒 【簡單grpc】rgpc 100000 次NettyServer調用,耗時:52138毫秒,平均1917次/秒 【簡單grpc】rgpc 100000 次NettyServer調用,耗時:51800毫秒,平均1930次/秒 【簡單grpc】rgpc 100000 次NettyServer調用,耗時:51313毫秒,平均1948次/秒 【簡單grpc】rgpc 100000 次NettyServer調用,耗時:56812毫秒,平均1760次/秒[2016-10-08 19:17:31] Dubbo service server started! 【dubbox.kryo】rgpc 100000 次NettyServer調用,耗時:55133毫秒,平均1813次/秒[2016-10-08 19:18:42] Dubbo service server started!【dubbox.kryo】rgpc 100000 次NettyServer調用,耗時:52280毫秒,平均1912次/秒[2016-10-08 19:20:01] Dubbo service server started! 【dubbox.kryo】rgpc 100000 次NettyServer調用,耗時:44414毫秒,平均2251次/秒[2016-10-08 19:13:34] Dubbo service server started! 【dubbox.fst】rgpc 100000 次NettyServer調用,耗時:44805毫秒,平均2231次/秒[2016-10-08 19:12:25] Dubbo service server started! 【dubbox.fst】rgpc 100000 次NettyServer調用,耗時:46245毫秒,平均2162次/秒[2016-10-08 19:14:43] Dubbo service server started! 【dubbox.fst】rgpc 100000 次NettyServer調用,耗時:12203毫秒,平均8194次/秒[2016-10-09 19:52:34] Dubbo service server started!【dubbox.thrift】rgpc 100000 次NettyServer調用,耗時:14142毫秒,平均7071次/秒[2016-10-09 19:30:17] Dubbo service server started!【dubbox.thrift】rgpc 100000 次NettyServer調用,耗時:13762毫秒,平均7266次/秒[2016-10-09 19:30:43] Dubbo service server started!【dubbox.thrift】rgpc 100000 次NettyServer調用,耗時:44334毫秒,平均2255次/秒 【motan】rgpc 100000 次NettyServer調用,耗時:37844毫秒,平均2642次/秒 【motan】rgpc 100000 次NettyServer調用,耗時:39007毫秒,平均2563次/秒 【motan】rgpc 100000 次NettyServer調用,耗時:38610毫秒,平均2590次/秒 【motan】
測試結果說明
使用的自己的膝上型電腦測試的,測試的方式可能不太專業,但能夠說明問題。通過上面結果可以看到,thrift的效能最好,而且是相當的好
網上其他人做的測試

ice-dubbo-thrift-grpc效能測試對比
RPC架構的效能比較 總結

影響RPC效能的因素主要有: 序列化效能 IO效能 線程模式

序列化的話,肯定是Google的PB協議和thrift最好,IO和線程的話,先流行的效能比較好的都是採用多線程非阻塞IO。

grpc是Google出品,使用了PB協議,但是由於它出現的比較晚,還不怎麼成熟,而且採用http協議,非常適合現在的微服務,不過效能上差了許多,而且像服務治理與監控都需要額外的開發工作,所以放棄grpc。
thrift和grpc一樣,效能優越,但是開發難度相比較於dubbox和motan也是高了一點點,需要編寫proto檔案(其實對於程式員來說這算不上難度)。像服務治理與監控也是需要額外的開發工作。
dubbo比較老了,直接棄用。
dubbox和後來的motan都比較適合我們的團隊。dubbox後來經過噹噹的開發,引入了rest風格的http協議,並且還支援kryo/fst/dubbo/thrift等其他協議,而且其他團隊也在使用dubbo,整合方便,服務治理監控功能齊全,所以最終採用dubbox。

其實我個人而言還是喜歡thrift,畢竟性嫩優越,在大型分布式系統中,哪怕一點點效能提升累計在一起也是很可觀的。不過再具體選型的過程中還要結合團隊目前的狀況和團隊其他開發人員的接受程度進行取捨。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.