面試官:消息隊列的應用場景有哪些?
通常來說,使用消息隊列主要能為我們的系統帶來下面三點好處:
- 異步處理
- 削峰/限流
- 降低系統耦合性
除了這三點之外,消息隊列還有其他的一些應用場景,例如實現分布式事務、順序保證和數據流處理。
如果在面試的時候你被面試官問到這個問題的話,一般情況是你在你的簡歷上涉及到消息隊列這方面的內容,這個時候推薦你結合你自己的項目來回答。
異步處理
通過異步處理提高系統性能
將用戶請求中包含的耗時操作,通過消息隊列實現異步處理,將對應的消息發送到消息隊列之后就立即返回結果,減少響應時間,提高用戶體驗。隨后,系統再對消息進行消費。
因為用戶請求數據寫入消息隊列之后就立即返回給用戶了,但是請求數據在后續的業務校驗、寫數據庫等操作中可能失敗。因此,使用消息隊列進行異步處理之后,需要適當修改業務流程進行配合,比如用戶在提交訂單之后,訂單數據寫入消息隊列,不能立即返回用戶訂單提交成功,需要在消息隊列的訂單消費者進程真正處理完該訂單之后,甚至出庫后,再通過電子郵件或短信通知用戶訂單成功,以免交易糾紛。這就類似我們平時手機訂火車票和電影票。
削峰/限流
先將短時間高并發產生的事務消息存儲在消息隊列中,然后后端服務再慢慢根據自己的能力去消費這些消息,這樣就避免直接把后端服務打垮掉。
舉例:在電子商務一些秒殺、促銷活動中,合理使用消息隊列可以有效抵御促銷活動剛開始大量訂單涌入對系統的沖擊。如下圖所示:
削峰
降低系統耦合性
使用消息隊列還可以降低系統耦合性。我們知道如果模塊之間不存在直接調用,那么新增模塊或者修改模塊就對其他模塊影響較小,這樣系統的可擴展性無疑更好一些。
生產者(客戶端)發送消息到消息隊列中去,消費者(服務端)處理消息,需要消費的系統直接去消息隊列取消息進行消費即可而不需要和其他系統有耦合,這顯然也提高了系統的擴展性。
發布/訂閱(Pub/Sub)模型
消息隊列使用發布-訂閱模式工作,消息發送者(生產者)發布消息,一個或多個消息接受者(消費者)訂閱消息。 從上圖可以看到消息發送者(生產者)和消息接受者(消費者)之間沒有直接耦合,消息發送者將消息發送至分布式消息隊列即結束對消息的處理,消息接受者從分布式消息隊列獲取該消息后進行后續處理,并不需要知道該消息從何而來。對新增業務,只要對該類消息感興趣,即可訂閱該消息,對原有系統和業務沒有任何影響,從而實現網站業務的可擴展性設計。
例如,我們商城系統分為用戶、訂單、財務、倉儲、消息通知、物流、風控等多個服務。用戶在完成下單后,需要調用財務(扣款)、倉儲(庫存管理)、物流(發貨)、消息通知(通知用戶發貨)、風控(風險評估)等服務。使用消息隊列后,下單操作和后續的扣款、發貨、通知等操作就解耦了,下單完成發送一個消息到消息隊列,需要用到的地方去訂閱這個消息進行消息即可。
圖片
另外,為了避免消息隊列服務器宕機造成消息丟失,會將成功發送到消息隊列的消息存儲在消息生產者服務器上,等消息真正被消費者服務器處理后才刪除消息。在消息隊列服務器宕機后,生產者服務器會選擇分布式消息隊列服務器集群中的其他服務器發布消息。
備注: 不要認為消息隊列只能利用發布-訂閱模式工作,只不過在解耦這個特定業務環境下是使用發布-訂閱模式的。除了發布-訂閱模式,還有點對點訂閱模式(一個消息只有一個消費者),我們比較常用的是發布-訂閱模式。另外,這兩種消息模型是 JMS 提供的,AMQP 協議還提供了另外 5 種消息模型。
實現分布式事務
分布式事務的解決方案之一就是 MQ 事務。
RocketMQ、 Kafka、Pulsar、QMQ 都提供了事務相關的功能。事務允許事件流應用將消費,處理,生產消息整個過程定義為一個原子操作。
RocketMQ 事務消息原理如下圖所示:
圖片
順序保證
在很多應用場景中,處理數據的順序至關重要。消息隊列保證數據按照特定的順序被處理,適用于那些對數據順序有嚴格要求的場景。大部分消息隊列,例如 RocketMQ、RabbitMQ、Pulsar、Kafka,都支持順序消息。
延時/定時處理
消息發送后不會立即被消費,而是指定一個時間,到時間后再消費。大部分消息隊列,例如 RocketMQ、RabbitMQ、Pulsar、Kafka,都支持定時/延時消息。
圖片
數據流處理
針對分布式系統產生的海量數據流,如業務日志、監控數據、用戶行為等,消息隊列可以實時或批量收集這些數據,并將其導入到大數據處理引擎中,實現高效的數據流管理和處理。