咱們來看看下面遇到的幾種業務場景
1)好比咱們在一些高併發環境下,來不及同步處理數據,請求每每就會發生阻塞。好比往mysql數據中大量的插入數據,那麼mysql可能由於量大一時處理不過來,致使鎖表。 這時候就能夠藉助隊列來異步處理。
也就是說,在系統中出現 「生成」 和 「消費」 的速度或者穩定性因素不一致的時候,就須要消息隊列,來彌合雙方的差別。php
2)有些業務不須要當即處理消息,而是能夠放到後面來進行處理。好比咱們註冊的時候須要發送郵件,註冊了後就能夠把須要發送郵件的消息投遞到消息隊列,讓其餘程序來單獨的處理髮送郵件的任務。java
3)好比說web用的是php,後端處理語言用的java,這種使用不一樣的語言,也可使用消息隊列mysql
4)還有一些任務系統,能夠先把用戶發起的任務請求接收過來發到消息隊列中,而後後端就能夠開啓多個程序來消費處理任務web
1)過載保護
在訪問量劇增的狀況下,應用仍然須要繼續發揮做用,可是這樣的突發流量沒法提取預知;若是覺得了能處理這類瞬間峯值訪問爲標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列可以使關鍵組件頂住突發的訪問壓力,而不會由於突發的超負荷的請求而徹底崩潰。還能夠用做錯峯與流控
2)異步通訊
有些業務不想也不須要當即處理消息。消息隊列提供了異步處理機制,容許用戶把一個消息放入隊列,但並不當即處理它。想向隊列中放入多少消息就放多少,而後在須要的時候再去處理它們。
3)解耦
下降工程間的強依賴程度,針對異構系統進行適配。在項目啓動之初來預測未來項目會碰到什麼需求,是極其困難的。經過消息系統在處理過程當中間插入了一個隱含的、基於數據的接口層,兩邊的處理過程都要實現這一接口,當應用發生變化時,能夠獨立的擴展或修改兩邊的處理過程,只要確保它們遵照一樣的接口約束。
4)擴展性
由於消息隊列解耦了你的處理過程,因此增大消息入隊和處理的頻率是很容易的,只要另外增長處理過程便可。不須要改變代碼、不須要調節參數。便於分佈式擴容。
5)冗餘
有些狀況下,處理數據的過程會失敗。除非數據被持久化,不然將形成丟失。消息隊列把數據進行持久化直到它們已經被徹底處理,經過這一方式規避了數據丟失風險。許多消息隊列所採用的"插入-獲取-刪除"範式中,在把一個消息從隊列中刪除以前,須要你的處理系統明確的指出該消息已經被處理完畢,從而確保你的數據被安全的保存直到你使用完畢
6)可恢復性
系統的一部分組件失效時,不會影響到整個系統。消息隊列下降了進程間的耦合度,因此即便一個處理消息的進程掛掉,加入隊列中的消息仍然能夠在系統恢復後被處理。
7)順序保證
在大多使用場景下,數據處理的順序都很重要。大部分消息隊列原本就是排序的,而且能保證數據會按照特定的順序來處理
8)緩衝
在任何重要的系統中,都會有須要不一樣的處理時間的元素。消息隊列經過一個緩衝層來幫助任務最高效率的執行,該緩衝有助於控制和優化數據流通過系統的速度。以調節系統響應時間
9)數據流處理
分佈式系統產生的海量數據流,如:業務日誌、監控數據、用戶行爲等,針對這些數據流進行實時或批量採集彙總,而後進行大數據分析是當前互聯網的必備技術,經過消息隊列完成此類數據收集是最好的選擇
10)最終一致性
最終一致性指的是兩個系統的狀態保持一致,要麼都成功,要麼都失敗。固然有個時間限制,理論上越快越好,但實際上在各類異常的狀況下,可能會有必定延遲達到最終一致狀態,但最後兩個系統的狀態是同樣的。
業界有一些爲「最終一致性」而生的消息隊列,如Notify(阿里)、QMQ(去哪兒)等,其設計初衷,就是爲了交易系統中的高可靠通知。sql
message channel模型後端
消息通道做爲在客戶端(消費者,Consumer)與服務(生產者,Producer)之間引入的間接層,能夠有效地解除兩者之間的耦合。只要實現規定雙方須要通訊的消息格式,以及處理消息的機制與時機,就能夠作到消費者對生產者的「無知」。事實上,該模式能夠支持多個生產者與消費者。例如,咱們可讓多個生產者向消息通道發送消息,由於消費者對生產者的無知性,它沒必要考慮到底是哪一個生產者發來的消息安全
發佈者-訂閱者(Publisher-Subscriber)模式
一旦消息通道須要支持多個消費者時,就可能面臨兩種模型的選擇:拉模型與推模型。拉模型是由消息的消費者發起的,主動權把握在消費者手中,它會根據本身的狀況對生產者發起調用
a) 拉模型
拉模型的另外一種體現則由生產者在狀態發生變動時,通知消費者其狀態發生了改變。但獲得通知的消費者卻會以回調方式,經過調用傳遞過來的消費者對象獲取更多細節消息服務器
b)推模型
推模型的主動權經常掌握在生產者手中,消費者被動地等待生產者發出的通知,這就要求生產者必須瞭解消費者的相關信息
對於推模型而言,消費者無需瞭解生產者。在生產者通知消費者時,傳遞的每每是消息(或事件),而非生產者自身。同時,生產者還能夠根據不一樣的狀況,註冊不一樣的消費者,又或者在封裝的通知邏輯中,根據不一樣的狀態變化,通知不一樣的消費者併發
兩種模型各有優點。拉模型的好處在於能夠進一步解除消費者對通道的依賴,經過後臺任務去按期訪問消息通道。壞處是須要引入一個單獨的服務進程,以Schedule形式執行。而對於推模型而言,消息通道事實上會做爲消費者觀察的主體,一旦發現消息進入,就會通知消費者執行對消息的處理。不管推模型,拉模型,對於消息對象而言,均可能採用相似Observer模式的機制,實現消費者對生產者的訂閱,所以這種機制一般又被稱爲Publisher-Subscriber模式異步
消息路由(Message Router)模式
不管是Message Channel模式,仍是Publisher-Subscriber模式,隊列在其中都扮演了舉足輕重的角色。然而,在企業應用系統中,當系統變得愈來愈複雜時,對性能的要求也會愈來愈高,此時對於系統而言,可能就須要支持同時部署多個隊列,並可能要求分佈式部署不一樣的隊列。
Broker:消息服務器,做爲server提供消息核心服務
Producer:消息生產者,業務的發起方,負責生產消息傳輸給broker,
Consumer:消息消費者,業務的處理方,負責從broker獲取消息並進行業務邏輯處理
Topic:主題,發佈訂閱模式下的消息統一聚集地,不一樣生產者向topic發送消息,由MQ服務器分發到不一樣的訂閱者,實現消息的廣播
Queue:隊列,PTP模式下,特定生產者向特定queue發送消息,消費者訂閱特定的queue完成指定消息的接收
Message:消息體,根據不一樣通訊協議定義的固定格式進行編碼的數據包,來封裝業務數據,實現消息的傳輸
參考:http://www.infoq.com/cn/articles/message-based-distributed-architecture