最近考慮把公司系統重構升級,將原有的垂直MVC架構遷移爲分佈式系統,因此着重瞭解了下遠程調用服務(RPC)和消息隊列(MQ)。RPC和MQ都是用於分佈式系統的兩個關鍵技術,並且裏面都有服務提供者和消費者的概念,可在一定程度上對系統進行解耦。但對於彼此應用場景的區分還不是特別清楚,直到看了一篇阿里內部人士寫的文章,簡單明瞭的介紹了兩者的區別和應用場景,現在貼出來和大家分享一下。
原文鏈接:http://oldratlee.com/post/2013-02-01/synchronous-rpc-vs-asynchronous-message
在阿里的平臺技術部參與開發了Dubbo(遠程調用服務)和Napoli(消息解決方案),又給網站應用支持這2個產品2年,瞭解了這2個產品的實現及應用對這兩個產品的用法。
大部分情況下,“給定場景下應該使用這兩個產品中哪個”這個問題,大家都會容易決定,而且不需要多少討論。
我爲什麼要拿出來討論一下:
- 一些場景會比較模糊,覺得都可以使用。這時需要知道產品缺點,而不是看到優勢。
- 一些新人會覺得產品功能是可以替換的,要給說明一下。
這裏簡單說一下兩者的區別。
系統結構
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
RPC系統結構: +----------+
+----------+ |
Consumer | <=> | Provider | +----------+
+----------+ Consumer調用的Provider提供的服務。 Message
Queue系統結構: +--------+
+-------+ +----------+ |
Sender | <=> | Queue | <=> | Receiver | +--------+
+-------+ +----------+ Sender發送消息給Queue;Receiver從Queue拿到消息來處理。 |
功能特點
在架構上,RPC和Message的差異點是,Message有一箇中間結點Message Queue,可以把消息存儲。
消息的特點
- Message Queue把請求的壓力保存一下,逐漸釋放出來,讓處理者按照自己的節奏來處理。
- Message Queue引入一下新的結點,讓系統的可靠性會受Message Queue結點的影響。
- Message Queue是異步單向的消息。發送消息設計成是不需要等待消息處理的完成。
所以對於有同步返回需求,用Message Queue則變得麻煩了。
RPC的特點
-
同步調用,對於要等待返回結果/處理結果的場景,RPC是可以非常自然直覺的使用方式。
# RPC也可以是異步調用。 - 由於等待結果,Consumer(Client)會有線程消耗。
如果以異步RPC的方式使用,Consumer(Client)線程消耗可以去掉。但不能做到像消息一樣暫存消息/請求,壓力會直接傳導到服務Provider。
適用場合說明
- 希望同步得到結果的場合,RPC合適。
- 希望使用簡單,則RPC;RPC操作基於接口,使用簡單,使用方式模擬本地調用。異步的方式編程比較複雜。
- 不希望發送端(RPC Consumer、Message Sender)受限於處理端(RPC Provider、Message Receiver)的速度時,使用Message Queue。
隨着業務增長,有的處理端處理量會成爲瓶頸,會進行同步調用到異步消息的改造。
這樣的改造實際上有調整業務的使用方式。
比如原來一個操作頁面提交後就下一個頁面會看到處理結果;改造後異步消息後,下一個頁面就會變成“操作已提交,完成後會得到通知”。
不適用場合說明
RPC同步調用使用Message Queue來傳輸調用信息。 上面分析可以知道,這樣的做法,發送端是在等待,同時佔用一箇中間點的資源。變得複雜了,但沒有對等的收益。
對於返回值是void的調用,可以這樣做,因爲實際上這個調用業務上往往不需要同步得到處理結果的,只要保證會處理即可。(RPC的方式可以保證調用返回即處理完成,使用消息方式後這一點不能保證了。)
返回值是void的調用,使用消息,效果上是把消息的使用方式Wrap成了服務調用(服務調用使用方式成簡單,基於業務接口)。
補記,關於解耦討論
微博上的一些討論,覺得很有意義補記下來。
inter12:這兩者可以拿來比較,但是個人感覺並不是同一個層面的問題。RPC是分佈式服務之間調用的一種解決方案,是我們在做架構設計決策時同分佈式對象,REST等層面的東西比較,決策的一個方案! 消息系統更多是我們爲了解決系統之間的解耦,以及性能問題等方面所考慮的方案! 說的有些亂,望鼎哥指點下。
oldratlee:回覆@inter12:你說到很多關鍵點了,“分佈式對象”“解耦”“性能”,這些都可以用來看兩者的差異。 如果從兩個機器間數據的傳遞(調用、消息都是數據)角度看,兩者效果相同,區別只是使用方式、技術指標:同步異步(比如 是否等反饋 )、數據是否暫存、強弱類型(比如 有獨立的業務方法,數據類型)等等
inter12提到了“解耦”,“解決系統之間的解耦”使用消息時大家常常說到的一點,一個重要權衡方面!
個人覺得,“解耦”不如“暫存”,是消息相對RPC的關鍵區別,原因說明如下:
消息的解耦特徵,主要體現在:
- 消息的發送者,不需要關心接收者的信息。 服務通過註冊中心也可以做到,即服務調用者到註冊中心查詢服務提供者信息,調用者不需知道。
-
消息的發送者,不用關心可以發個幾個關心的消息組件。
這一點RPC可以通過服務編排做到。