其實這個問題本身是有些問題的,任務(wù)隊列,消息隊列和RPC完全是幾個不相關(guān)的概念,或者說它們并不是同一層面的概念,如果非要扯上一些關(guān)系的話,那么任務(wù)隊列可以通過消息隊列實現(xiàn),RPC和消息隊列是同步和異步的差別。
任務(wù)隊列
我還沒有聽說過一個叫做任務(wù)隊列的框架、中間件或其他任務(wù)和技術(shù)有關(guān)的名詞;我能想象到的任務(wù)隊列,更多的是一個業(yè)務(wù)概念,當有很多任務(wù)(硬件資源不足以同時處理這些任務(wù)),或任務(wù)和任務(wù)之間有先后順序的時候,可以通過對其進行排序處理,這就是任務(wù)隊列。
RPC
RPC:RemoteProcedureCall,中文意思就是遠程過程調(diào)用。
遠程是相對于本地來說的,有遠程調(diào)用就有本地調(diào)用,那么先說說本地調(diào)用是什么,這個就簡單了;
比如下圖,我們的代碼在同一個進程中(或者說同一個地址空間)調(diào)用另外一個方法,得到我們需要的結(jié)果,這就是本地調(diào)用:
那么想象一下,如果這里的add方法是一個很復(fù)雜的方法,很多系統(tǒng)都想用這個方法,那么我們可以把這個方法單獨拆成一個服務(wù),提供給各個系統(tǒng)進行調(diào)用,那么本地就會變成遠程,就會變成這樣:
很多人都會想到Server_B封裝一個接口,通過服務(wù)把這個方法暴露出去,比如通過HTTP請求,那么Server_A就可以調(diào)用Server_B中的add方法了。
通過這種方法實現(xiàn)起來沒有問題,也是一個不錯的解決方法,就是在每次調(diào)用的時候,都要發(fā)起HTTP請求,代碼里面要寫HttpClient.sendRequest這樣的代碼,那么我們有沒有可能像調(diào)用本地一樣,去發(fā)起遠程調(diào)用呢?讓程序員不知道這是調(diào)用的遠程方法呢?這時候就要提到RPC了(并不是說RPC優(yōu)于HTTP請求,關(guān)于這兩個概念我們在下文中討論)。
完整的RPC過程,如圖:
服務(wù)調(diào)用方(Client)調(diào)用以本地調(diào)用方式調(diào)用服務(wù);
Clientstub負責(zé)將方法名、參數(shù)組裝成消息體并進行序列化,找到服務(wù)地址,將消息發(fā)送到服務(wù)端;
Serverstub收到消息后進行反序列化后調(diào)用本地的服務(wù);
本地服務(wù)執(zhí)行,將結(jié)果返回給Serverstub;
Serverstub將運行結(jié)果打包成消息序列化后,發(fā)送調(diào)用方;
Clientstub接收到消息,并進行反序列化,調(diào)用方最終得到調(diào)用結(jié)果。
總結(jié)來說,RPC用于服務(wù)之間的調(diào)用問題,特別是分布式環(huán)境;RPC讓遠程調(diào)用時,像調(diào)用本地方法一樣方便和無感知;RPC框架屏蔽了很多底層的細節(jié),不需要開發(fā)人員關(guān)注這些細節(jié),比如序列化和反序列化、網(wǎng)絡(luò)傳輸協(xié)議的細節(jié)。
消息隊列
在正式講解之前,讓我們看一個簡單的場景:
用戶支付成功后,發(fā)送一條提示短信;假設(shè)支付的時候會調(diào)用支付系統(tǒng)的接口,所需時間Xms,發(fā)送短信會調(diào)用短信平臺的接口,所需時間Yms,那么支付動作一共需要(X+Y)ms,如果Y值比較大的時候,會造成整個支付過程很慢,那么我們有沒有更好的解決方案呢?
下面,讓我們帶著這個問題來了解一下什么是消息隊列,以及消息隊列的使用場景。
我們可以把消息隊列看做是一個存放消息的容器,我們可以往這個容器中放入消息,也可以從這個容器中取出消息;放入消息的叫做生產(chǎn)者,取走消息的叫做消費者;
點對點:如果生產(chǎn)者放入一條消息,只能被一個消費者取走一次,這叫做點對點模式;(pointtopoint,queue); 發(fā)布/訂閱:如果生產(chǎn)者放入一條消息,可以被多個消費者取走,這叫做發(fā)布/訂閱模式;(publish/subscribe,topic);
我覺得使用消息隊列主要有兩點好處:
如果A系統(tǒng)直接調(diào)用B系統(tǒng)的接口,那么當B系統(tǒng)出現(xiàn)故障的時候,A系統(tǒng)也會受到影響;如果A和B之間不直接進行調(diào)用,那么耦合度就會變得很低。
還是A系統(tǒng)調(diào)用B系統(tǒng)的接口,還有另外一種場景,A發(fā)起的調(diào)用量在某個時間段突然增多,很可能導(dǎo)致B系統(tǒng)崩潰宕機;這時,A系統(tǒng)可以將請求發(fā)送到消息隊列中,B系統(tǒng)按照自己的處理能力,從消息隊列中訂閱消息進行處理,達到了流量削鋒的效果。
我們再回到上面的問題,是不是使用消息隊列就可以很好的解決這個問題了;給客戶發(fā)送短信這個業(yè)務(wù)場景,時效性要求并不高,所以完全可以在支付過程中,把通知短信發(fā)到消息隊列中,再由短信平臺消費信息發(fā)送短信。