消息隊列(一)

消息隊列MQ

維基百科中是這樣介紹消息隊列的html

消息隊列(Message queue)是一種進程間通訊或同一進程的不一樣線程間的通訊方式,軟件的貯列用來處理一系列的輸入,一般是來自用戶。消息隊列提供了異步的通訊協議,每個貯列中的紀錄包含詳細說明的數據,包含發生的時間,輸入設備的種類,以及特定的輸入參數,也就是說:消息的發送者和接收者不須要同時與消息隊列交互。消息會保存在隊列中,直到接收者取回它java

58沈劍是這樣介紹消息隊列的git

消息隊列,是一種跨進程的通訊機制,用於上下游傳遞消息。在互聯網架構中,MQ是一種很是常見的上下游「邏輯解耦+物理解耦」的消息通訊服務。使用MQ後,消息發送上游只須要依賴MQ,邏輯上和物理上不依賴與下游。github

消息隊列的應用場景

  • 異步處理: 將非核心流程異步化,提升系統響應性能。好比用戶註冊須要發送郵件和短信確認(雖然產品都不會這樣作,僅僅舉例),咱們能夠在註冊成功後發送消息給MQ,而後郵件服務和短信服務接受消息後執行。這裏,能夠直接使用線程完成,可是咱們可使用MQ後,咱們不用關心下游(郵件、短信服務等)有多少任務,而且咱們能夠簡單的在下游訂閱上游便可動態添加。
  • 應用解耦: 將不強依賴於本系統的非核心流程和系統流程進行解耦。好比購買商品後會有積分贈送,這裏積分系統時非核心流程,咱們可讓訂單系統和積分系統解耦。
  • 流量削峯與流控控制: 當上下游系統處理能力存在差距的時候,利用消息隊列作一個通用的「漏斗」。在下游有能力處理的時候,再進行分發。例如,在秒殺系統中咱們能夠把用戶請求寫入消息隊列中,而後秒殺系統在根據規則依次從消息隊列中取而後進行處理,這樣就不會發送系統因爲併發量過大而崩潰。
  • 消息訂閱: 這裏有點像UDP,上游只關心把消息放入MQ中,下游誰訂閱了就會得到消息。
  • 消息通信: MQ都會內置高效的通訊機制,例如咱們可使用MQ做爲通訊工具進行RPC通訊。
  • 日誌處理: 使用MQ解決大量日誌傳輸問題。

日誌處理(轉自新浪是如何分析處理32億條實時日誌的?)
mark服務器

電商系統(轉自大型網站架構系列:分佈式消息隊列(一))微信

mark

消息隊列的不足

  • 系統更加複雜,多了MQ組件
  • 消息可靠性和重複性互爲矛盾,消息不丟不重難以同時保證
  • 上游沒法知道下游的執行結果

調用方實時依賴執行結果的業務場景,使用調用,而不是MQ網絡

消息隊列的消息協議

常見的MQ有RabbitMQ、ActiveMQ、Kafka、RocketMQ等等,它們支持不一樣的通訊協議.例如AMQP、SMTP、STOMP、HTTP等等,下面是一下協議介紹。架構

AMQP

AMQP(高級消息隊列協議)是應用層網絡協議,它支持符合要求的客戶端應用和消息中間件代理之間通訊。併發

圖來自網絡

AMQP協議的各個部分app

  • AMQP協議中的元素包括:Message(消息體)、Producer(生產者)、Consumer(消費者)、Virtual Host(虛擬節點)、Exchange(交換機)、Queue(隊列)等
  • 由Producer(消息生產者)和Consumer(消息消費者)構成了AMQP的客戶端,他們是發送消息和接收消息的主體。AMQP服務端稱爲Broker,一個Broker中必定包含完整的Virtual Host(虛擬主機)、 Exchange(交換機)、Queue(隊列)定義
  • 一個Broker能夠建立多個Virtual Host(虛擬主機),咱們將討論的Exchange和Queue都是虛擬機中的工做元素(還有User元素)。注意,若是AMQP是由多個Broker構成的集羣提供服務,那麼一個Virtual Host也能夠由多個Broker共同構成
  • Connection是由Producer(消息生產者)和Consumer(消息消費者)建立的鏈接,鏈接到Broker物理節點上。可是有了Connection後客戶端還不能和服務器通訊,在Connection之上客戶端會建立Channel,鏈接到Virtual Host或者Queue上,這樣客戶端才能向Exchange發送消息或者從Queue接受消息。一個Connection上容許存在多個Channel,只有Channel中可以發送/接受消息
  • Exchange元素是AMQP協議中的交換機,Exchange能夠綁定多個Queue也能夠同時綁定其餘Exchange。消息經過Exchange時,會按照Exchange中設置的Routing(路由)規則,將消息發送到符合的Queue或者Exchange中

AMQP中消息的交互

  1. 在Producer(消息生產者)客戶端創建了Channel後,就創建了到Broker上Virtual Host的鏈接。接下來Producer就能夠向這個Virtual Host中的Exchange發送消息了
  2. Exchange(交換機)可以處理消息的前提是:它至少已經和某個Queue或者另外的Exchange造成了綁定關係,並設置好了到這些Queue和Excahnge的Routing(路由規則)。Exchange中的Routing有三種模式,在Exchange收到消息後,會根據設置的Routing(路由規則),將消息發送到符合要求的Queue或者Exchange中(路由規則還會和Message中的Routing Key屬性配合使用)
  3. Queue收到消息後,可能會進行以下的處理:若是當前沒有Consumer的Channel鏈接到這個Queue,那麼Queue將會把這條消息進行存儲直到有Channel被建立(AMQP協議的不一樣實現產品中,存儲方式又不盡相同);若是已經有Channel鏈接到這個Queue,那麼消息將會按順序被髮送給這個Channel
  4. Consumer收到消息後,就能夠進行消息的處理了。可是整個消息傳遞的過程尚未完成:視設置狀況,Consumer在完成某一條消息的處理後,將須要手動的發送一條ACK消息給對應的Queue(固然您能夠設置爲自動發送,或者無需發送)。Queue在收到這條ACK信息後,纔會認爲這條消息處理成功,並將這條消息從Queue中移除;若是在對應的Channel斷開後,Queue都沒有這條消息的ACK信息,這條消息將會從新被髮送給另外的Channel。固然,您還能夠發送NACK信息,這樣這條消息將會當即歸隊,併發送給另外的Channel

AMQP協議中的Message

AMQP協議的消息格式以下:

圖來自網絡

其中內容在PAYLOAD部分,PAYLOAD部分格式以下:

mark

關於AMQP更加詳細的資料見於:AMQP官網關於AMQP網友的博客

STOMP

STOMP(簡單文本定向協議)一樣是應用層協議,它提供一個可交互操做的鏈接格式,允許STOMP客戶端和任意STOMP消息代理(Broker)進行交互,經常使用於消息中間件。STOMP協議基於幀(Frame)進行通訊,第一行包含命令,而後緊跟鍵值對形式的Header內容,第二行空行,第三行開始就是Body內容,末尾都以空字符結尾。

STOMP消息格式和HTTP請求很像,格式以下:

COMMAD
header1:value1
header2:value2
...

Body

常見幀命令有:

  • CONNECT
  • SEND
  • SUBSCRIBE
  • UNSUBSCRIBE
  • ACK
  • NACK
  • ...

例如STOMPSEND消息:

SEND
destination:/app/hello
content-length:20

{"message":"World!"}

關於STOMP資料見於:STOMP1.2官方規範關於STOMP網友的博客

JMS

JMS(Java消息服務)不是網絡協議,其是Java關於消息服務提供了一組通用接口,具體實現的協議由使用該接口的應用程序實現。在MQ中ActiveMQ、RocketMQ都實現了該協議。

這裏有篇介紹JMS文章:JMS學習一(JMS介紹)

Reference

http://blog.csdn.net/u012758088/article/details/78024581
https://www.cnblogs.com/my_life/articles/7002138.html
https://www.jianshu.com/p/cee941ca0c09 架構師之路工做號《到底何時該使用MQ?》(因爲微信公衆號文章URL有時間限制,因此沒有列出來)

相關文章
相關標籤/搜索