什么是消息隊列?
MQ全程(Message Queue)又名消息隊列,是一種異步通訊的中間件。可以理解為郵局,發送者將消息投遞到郵局,然后郵局幫我們發送給具體的接收者,具體發送過程和時間與我們無關。
消息隊列是分布式系統中重要的組件,消息隊列主要解決了應用耦合、異步處理、流量削鋒等問題。
當前使用較多的消息隊列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,而部分數據庫如Redis、Mysql以及phxsql也可實現消息隊列的功能。
使用場景
消息隊列在實際應用中包括如下四個場景:
-
應用耦合:多應用間通過消息隊列對同一消息進行處理,避免調用接口失敗導致整個過程失敗;
-
異步處理:多應用對消息隊列中同一消息進行處理,應用間並發處理消息,相比串行處理,減少處理時間;
-
限流削峰:廣泛應用於秒殺或搶購活動中,避免流量過大導致應用系統掛掉的情況;
-
消息驅動的系統:系統分為消息隊列、消息生產者、消息消費者,生產者負責產生消息,消費者(可能有多個)負責對消息進行處理;
下面詳細介紹上述四個場景以及消息隊列如何在上述四個場景中使用:
異步處理
具體場景:用戶為了使用某個應用,進行注冊,系統需要發送注冊郵件並驗證短信。對這兩個操作的處理方式有兩種:串行及並行。
1)串行方式:將注冊信息寫入數據庫成功后,發送注冊郵件,再發送注冊短信。以上三個任務全部完成后,返回給客戶端
2)並行方式:將注冊信息寫入數據庫成功后,發送注冊郵件的同時,發送注冊短信。以上三個任務完成后,返回給客戶端。與串行的差別是,並行的方式可以提高處理的時間
小結:假設三個業務節點分別使用50ms,串行方式使用時間150ms,並行使用時間100ms。雖然並性已經提高的處理時間,但是,前面說過,郵件和短信對我正常的使用網站沒有任何影響,客戶端沒有必要等着其發送完成才顯示注冊成功,
應該是寫入數據庫后就返回.
引入消息隊列,將不是必須的業務邏輯,異步處理。改造后的架構如下:
按照以上約定,用戶的響應時間相當於是注冊信息寫入數據庫的時間,也就是50毫秒。注冊郵件,發送短信寫入消息隊列后,直接返回,因此寫入消息隊列的速度很快,基本可以忽略,因此用戶的響應時間可能是50毫秒。因此架構改變后,系統的吞吐量提高到每秒20 QPS。比串行提高了3倍,比並行提高了兩倍
應用耦合
場景說明:用戶下單后,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。如下圖
傳統模式的缺點:
-
假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗
-
訂單系統與庫存系統耦合
-
訂單系統:用戶下單后,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功
-
庫存系統:訂閱下單的消息,采用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操作
-
假如:在下單時庫存系統不能正常使用。也不影響正常下單,因為下單后,訂單系統寫入消息隊列就不再關心其他的后續操作了。實現訂單系統與庫存系統的應用解耦
解耦是消息中間件的一個主要作用,標准的用法是:
生產者生產消息傳送到隊列,消費者從隊列中拿取消息並處理,生產者不用關心是誰來消費,消費者不用關心誰在生產消息,從而達到解耦的目的。
限流削峰
具體場景:購物網站開展秒殺活動,一般由於瞬時訪問量過大,服務器接收過大,會導致流量暴增,相關系統無法處理請求甚至崩潰。而加入消息隊列后,系統可以從消息隊列中取數據,相當於消息隊列做了一次緩沖。
-
可以控制活動的人數
-
可以緩解短時間內高流量壓垮應用
-
用戶的請求,服務器接收后,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接拋棄用戶請求或跳轉到錯誤頁面
-
秒殺業務根據消息隊列中的請求信息,再做后續處理
比方說一個秒殺需求,一用有1萬件商品,如果每筆秒殺訂單,都去訪問一次數據庫,查一查庫存,那得花費多長時間啊。
我們可以這樣做,用一個消息隊列,定制它的長度為1萬,1萬以內可以存到消息隊列,並立馬反饋秒殺成功,之后再去做減庫存等一系列操作。一萬以后不再近消息隊列,並立馬反饋秒殺失敗。
以上內容的來源是:https://blog.csdn.net/whoamiyang/article/details/54954780,在此感謝
消息驅動的系統
具體場景:用戶新上傳了一批照片, 人臉識別系統需要對這個用戶的所有照片進行聚類,聚類完成后由對賬系統重新生成用戶的人臉索引(加快查詢)。這三個子系統間由消息隊列連接起來,前一個階段的處理結果放入隊列中,后一個階段從隊列中獲取消息繼續處理。
該方法有如下優點:
-
避免了直接調用下一個系統導致當前系統失敗;
-
每個子系統對於消息的處理方式可以更為靈活,可以選擇收到消息時就處理,可以選擇定時處理,也可以划分時間段按不同處理速度處理;
消息隊列的兩種模式
消息隊列包括兩種模式,點對點模式(point to point, queue)和發布/訂閱模式(publish/subscribe,topic)。
點對點式
生產者生產消息,存到消息隊列中去,消費者去消息隊列里邊消費。消費者在成功接收消息之后需向隊列應答成功,以便消息隊列刪除當前消費的消息,從而保證不重復消費信息
點對點模式特點:
-
每個消息只有一個接收者(Consumer)(即一旦被消費,消息就不再在消息隊列中);
-
發送者和接收者間沒有依賴性,發送者發送消息之后,不管有沒有接收者在運行,都不會影響到發送者下次發送消息;
-
接收者在成功接收消息之后需向隊列應答成功,以便消息隊列刪除當前接收的消息;
發布訂閱式:
發布者將消息發送到Topic,系統將這些消息傳遞給多個訂閱者。
發布/訂閱模式特點:
-
每個消息可以有多個訂閱者;
-
發布者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須創建一個訂閱者之后,才能消費發布者的消息。
-
為了消費消息,訂閱者需要提前訂閱該角色主題,並保持在線運行;
常用消息隊列介紹
TPS比較 一ZeroMq 最好,RabbitMq 次之, ActiveMq 最差。
持久化消息比較—zeroMq不支持,activeMq和rabbitMq都支持。持久化消息主要是指:MQ down或者MQ所在的服務器down了,消息不會丟失的機制。
可靠性、靈活的路由、集群、事務、高可用的隊列、消息排序、問題追蹤、可視化管理工具、插件系統、社區—RabbitMq最好,ActiveMq次之,ZeroMq最差。
高並發—從實現語言來看,RabbitMQ最高,原因是它的實現語言是天生具備高並發高可用的erlang語言。
綜上所述:RabbitMQ的性能相對來說更好更全面,是消息中間件的首選。
這里列舉了上述四種消息隊列的差異對比:
五、參考資料:
5.1 消息隊列:
-
大型網站架構之分布式消息隊列 http://blog.csdn.net/shaobingj126/article/details/50585035
-
消息隊列的使用場景 https://www.zhihu.com/question/34243607/answer/127666030
-
淺談異步消息隊列模型 http://www.cnblogs.com/sunkeydev/p/5248855.html
-
消息隊列的兩種模式 http://blog.csdn.net/heyutao007/article/details/50131089
5.2 RabbitMQ
-
RabbitMQ主頁 https://www.rabbitmq.com/
-
RabbitMQ學習教程 https://www.rabbitmq.com/getstarted.html
-
專欄:RabbitMQ從入門到精通 http://blog.csdn.net/column/details/rabbitmq.html
-
RabbitMQ能為你做些什么 http://rabbitmq.mr-ping.com/description.html
-
RabbitMQ指南(1)-特性及功能 https://blog.zenfery.cc/archives/79.html
5.3 ActiveMQ
-
ActiveMQ主頁 http://activemq.apache.org/
-
Apache ActiveMQ介紹 http://jfires.iteye.com/blog/1187688
-
ActiveMQ的簡介與安裝 http://blog.csdn.net/sl1992/article/details/72824562
-
ActiveMQ 和消息簡介 http://www.cnblogs.com/craftsman-gao/p/7002605.html
5.4 RocketMQ
-
主頁 https://github.com/alibaba/RocketMQ
-
RocketMQ 原理簡介 http://alibaba.github.io/RocketMQ-docs/document/design/RocketMQ_design.pdf
-
RocketMQ與kafka對比(18項差異) http://jm.taobao.org/2016/03/24/rmq-vs-kafka/
5.5 Kafka
1.Kafka主頁: http://kafka.apache.org/
-
Kafka特性 http://www.cnblogs.com/lsx1993/p/4847719.html
-
Kafka客戶端支持語言 https://cwiki.apache.org/confluence/display/KAFKA/Clients
5.6 RabbitMQ/ActiveMQ/RocketMQ/Kafka對比
-
RocketMQ,隊列選型 http://www.zmannotes.com/index.php/2016/01/17/rocketmq/
-
RabbitMQ和Kafka http://www.dongcoder.com/detail-416804.html
-
即時通信RabbitMQ二-性能測試 http://www.jianshu.com/p/d31ae9e3bfb6
-
RabbitMq、ActiveMq、ZeroMq、kafka之間的比較,資料匯總 http://blog.csdn.net/linsongbin1/article/details/47781187
-
消息隊列軟件產品大比拼 http://www.cnblogs.com/amityat/archive/2011/08/31/2160293.html
總結:
消息隊列利用高效可靠的消息傳遞機制進行平台無關的數據交流,並基於數據通信來進行分布式系統的集成。目前業界有很多的MQ產品,例如RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,也有直接使用數據庫redis充當消息隊列的案例。而這些消息隊列產品,各有側重,在實際選型時,需要結合自身需求及MQ產品特征,綜合考慮。
(原文地址:https://cloud.tencent.com/community/article/129032 。 尊重原創,感謝作者!)