本系列是「RabbitMQ實戰:高效部署分散式訊息佇列」書籍的總結筆記。
通過前2篇的介紹,瞭解了訊息通訊的主要元素和互動過程,以及如何執行和管理RabbitMQ,這篇將站在開發模式的角度理解「面向訊息通訊」帶來的好處,以及在各種場景下的最佳實踐。
通過介紹,你會了解到:
- 面向訊息通訊的好處
- 發後即忘模型
- 用RabbitMQ實現RPC
面向訊息通訊的好處
主要從非同步狀態思維、處理能力擴充套件性、整合複雜度方面,說明面向訊息通訊的好處。
非同步狀態思維
當將訊息通訊整合到應用程式時,開發模式將從同步模型變為非同步模型,RabbitMQ提供了不同的方法,允許我們在一處傳送請求,在另一處進行處理,這樣同步程式可以繼續執行其他邏輯。
舉個簡單的例子來說明,通過支付寶還信用卡:
- 使用者填寫信用卡號、髮卡銀行、持卡人姓名、還款金額,提交還款申請;
- 支付寶會立即提示使用者,申請已提交,多少小時內完成還款;
- 還款完成後,會推送給使用者一條訊息,提醒還款是否成功;
如果是同步請求,使用者需要等待幾個小時檢視結果,等待過程中不能進行其他操作,這是很不合理的。
非同步的思維是將請求和處理分離,在應用中緊密耦合的兩部分中間使用RabbitMQ,請求解析後,傳送一條業務能夠理解的訊息到RabbitMQ,就返回給使用者,真正的處理由另外的服務非同步處理。
擴充套件性
隨著業務的擴充套件,對服務處理能力的要求越來越高,RabbitMQ可以很簡單的增加處理能力。
因為RabbitMQ可以將請求在處理伺服器間平均地分發,不需要負載均衡器了。
零成本API
系統間相互呼叫,需要約定一套API,通常來講,需要花費一點點時間,編寫一大段程式碼將傳入的HTTP請求轉化為應用程式中的函式呼叫。
如果使用AMQP來連線應用程式的各個部分,無需額外定義API,使用訊息通訊即可。另外, AMQP是語言無關的,擁有數十種語言的本地語言繫結。
發後即忘模型
當考慮訊息通訊能夠解決的問題型別時,訊息通訊適用的主要領域是的「發後即忘」處理模式。關心的是任務將會完成,但無須實時完成,建立一個任務,傳送到交換器上後,就可以返回繼續工作,甚至都不需要通知使用者任務已經完成。
匹配該模式的兩種型別任務:
- 批處理:針對大型資料集合的工作或者轉換,多個任務對資料集合的獨立部分進行操作;
- 通知:對傳送事件的描述,可以是訊息的日誌,或者通知另一個程式或者管理員;
書上介紹的例項比較簡單,就不在此列出了,主要是根據不同的場景,確定交換器的型別和routingkey,可以參考上一篇介紹的「收集日誌」的例子進行理解。
用RabbitMQ實現RPC
有多種方式來實現遠端過程呼叫RPC,比如REST API、SOAP、Thrift等,這些傳統的RPC實現方法有共同之處:客戶端和伺服器緊密相連、而且要等待返回結果。另外考慮這些問題:
- 當有多個服務節點時,客戶端如何發現對應伺服器;
- 如果客戶端連線的RPC伺服器崩潰了,客戶端需要額外邏輯進行重連;
通過MQ伺服器來實現時,只是簡單地釋出訊息而已,將訊息路由到合適的地方放,通過多臺RPC伺服器對訊息進行負載均衡,當處理訊息的伺服器崩潰時,將RPC訊息重發到另一臺。
現在的問題在於,如果將應答返回給客戶端?
RabbitMQ使用訊息來發回應答,在AMQP訊息頭裡有一個欄位叫做reply_to,訊息的生成者可以通過該欄位來確定佇列名稱,並監聽佇列等待應答,訊息接收者能夠檢查reply_to欄位,並建立包含應答內容的新的訊息,並以佇列名稱作為路由鍵。
關於reply_to的佇列名稱,如果生成者宣告瞭沒有名字的佇列,RabbitMQ為自動生成一個唯一的佇列名,同時在宣告的時候指定exclusive引數,確保只有建立佇列的生產者可以讀取佇列上的訊息。
這樣,所有RPC客戶端要做的,就是宣告臨時的、排他的、匿名佇列,並將該佇列名稱包含到RPC訊息的reply_to頭中,這樣伺服器端就知道應答訊息該發往哪兒了。
很多場景使用「發後即忘」模型,不需要處理者響應,如果需要響應,可以使用RabbitMQ的RPC模型。
下一篇將介紹RabbitMQ叢集和高可用性以及它們的設定。
歡迎掃描下方二維碼,關注我的個人微信公眾號 ~