
旁白:這是一篇拖更了N久的文章...0.0(看不見我~)
往期回顧
安全框架 Shiro 和 Spring Security 如何選擇?
正文
消息隊列(MQ)
在百度百科中,消息隊列(MQ)是這么解釋的:“消息隊列”是在消息的傳輸過程中保存消息的容器(可存可取)。
它是分布式系統中重要的組件,使用消息隊列主要是為了通過異步處理提高系統性能和削峰和降低系統耦合性。
-
異步處理:多應用對消息隊列中同一消息進行處理,應用間並發處理消息,相比較串行處理,減少處理時間;
-
應用耦合:多應用通過消息隊列對同一消息進行處理,避免調用接口失敗導致整個過程失敗;
-
限流消峰:廣泛應用於秒查或搶購活動中,避免某一刻流量過導致應用系統掛掉的情況;
目前使用較多的消息隊列有 ActiveMQ 、RocketMQ 、RabbitMQ 和 Kafka 等。
點對點模式下包括三個角色:
-
消息隊列
-
發送者 (生產者)
-
接收者(消費者)
消息發送者生產消息發送到queue中,然后消息接收者從queue中取出並且消費消息。消息被消費以后,queue中不再有存儲,所以消息接收者不可能消費到已經被消費的消息。
點對點模式特點:
-
每個消息只有一個接收者(Consumer)(即一旦被消費,消息就不再在消息隊列中);
-
發送者和接收者間沒有依賴性,發送者發送消息之后,不管有沒有接收者在運行,都不會影響到發送者下次發送消息;
-
接收者在成功接收消息之后需向隊列應答成功,以便消息隊列刪除當前接收的消息;
發布/訂閱模式下包括三個角色:
-
角色主題(Topic)
-
發布者(Publisher)
-
訂閱者(Subscriber)
發布者將消息發送到Topic,系統將這些消息傳遞給多個訂閱者。
發布/訂閱模式特點:
-
每個消息可以有多個訂閱者;
-
發布者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須創建一個訂閱者之后,才能消費發布者的消息。
-
為了消費消息,訂閱者需要提前訂閱該角色主題,並保持在線運行;
異步處理
具體場景:用戶為了使用某個應用,進行注冊,系統需要發送注冊郵件和注冊短信。
對於該流程有兩種處理方式:並行和串行。
1)串行處理:寫入注冊信息后,先發送注冊郵件,再發送注冊短信。
這種方式下,需要等發送短信處理完成后才完成注冊。
2)並行處理:寫入注冊信息后,同時處理發郵件和發短信。
這種方式下,需要等發送短信和發送郵件處理完成后才完成注冊。

-
系統可用性降低系統引入的外部依賴越多,越容易掛掉。本來你就是 A 系統調用 BCD 三個系統的接口就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 掛了咋整,MQ 一掛,整套系統崩潰的,你不就完了?如何保證消息隊列的高可用,可以點擊這里查看。
-
系統復雜度提高硬生生加個 MQ 進來,你怎么保證消息沒有重復消費?怎么處理消息丟失的情況?怎么保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。
-
一致性問題A 系統處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統那里,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這數據就不一致了。


廣泛來說,電商、金融等對事務性要求很高的,可以考慮RabbitMQ和RocketMQ,對性能要求高的可考慮Kafka。
本文原發於 同名微信公眾號「程序員的成長之路」,回復「1024」你懂得,給個贊唄。
回復 [ 520 ] 領取程序員最佳學習方式
回復 [ 256 ] 查看 Java 程序員成長規划
