世界將我包圍 誓死都一齊
壯觀得有如 懸崖的婚禮
概述
消息隊列,簡稱MQ(Message Queue), 目的是爲了提升系統的異步通訊、擴展解耦能力java
- 如註冊爲列子,通常註冊成功後會發送一條消息給用戶,若是當咱們將數據保存成功後,繼續執行發送消息的邏輯,這時候系統就是在等待發送邏輯運行,會下降系統的速度;其實註冊成功後發送消息不是要當即響應成功的,咱們能夠註冊成功後,將要發送的消息放入消息隊列,而後發送消息的邏輯代碼根據消息隊列信息去執行,便提升了系統的運行速度
- 還應用在訂單系統的應用解耦,秒殺系統的流量削峯
兩種形式
- 隊列(queue):點對點消息通訊
- 主題(topic):發佈(publish)/訂閱(subscribe)消息通訊
點對點式:
- 消息發送者發送消息,消息代碼將其放入一個隊列中,消息接受者從隊列獲取消息,消息讀取後移出隊列
- 消息只有惟一的發送者和接受者,但不是隻有一個接收者,即A、B、C都接收到了這個消息,但是消息被A所接受了,B、C接收到了可是使用不了
訂閱式:
- 發送者發送消息到主題,多個接受者監聽訂閱這個主題,那麼消息在到達的同時收到消息
JMS和AMQP
- JMS(Java Message Service),JAVA消息服務,是一個API;基於JVM消息代理的規範,ActiveMQ是JMS實現的
- AMQP(Advanced Message Queuing Protocol),是一個高級消息隊列協議,兼容JMS,RabbitMQ是AMQP的實現
RabbitMQ簡介
RabbitMQ從總體上來看是一個典型的生產者消費者模型,主要負責接收、存儲和轉發消息。
架構圖以下:spring
Product,生產者
- 生產者鏈接到RabbitMQ Broker,創建一個鏈接( Connection)開啓一個信道(Channel)
- 生產者聲明一個交換器,並設置相關屬性,好比交換機類型、是否持久化等
- 生產者聲明一個隊列井設置相關屬性,好比是否排他、是否持久化、是否自動刪除等
- 生產者經過路由鍵將交換器和隊列綁定起來
- 生產者發送消息至RabbitMQ Broker,其中包含路由鍵、交換器等信息。
- 相應的交換器根據接收到的路由鍵查找相匹配的隊列。
- 若是找到,則將從生產者發送過來的消息存入相應的隊列中。
- 若是沒有找到,則根據生產者配置的屬性選擇丟棄仍是回退給生產者
- 關閉信道,關閉鏈接。
Exchange,交換器
在RabbitMQ中,生產者並不是直接將消息投遞到隊列中。真實狀況是,生產者將消息發送到Exchange(交換器),由交換器根據路由規則將消息路由到一個或多個隊列中。若是路由不到,或返回給生產者,或直接丟棄,或作其它處理。架構
RoutingKey,路由KEY
指定消息的路由規則,須要與交換器類型和綁定鍵(Binding)聯合使用才能最終生效,在綁定的條件下,生產者能夠在發送消息給交換器時經過指定RoutingKey來決定消息流向哪一個消息隊列。異步
Binding
將交換器和隊列關聯起來,決定交換器的消息發送到哪一個隊列上性能
Queue,隊列
- RabbitMQ的內部對象,用於存儲消息
- 生產者投遞消息到隊列,消費者從隊列中獲取消息並消費
- 多個消費者能夠訂閱同一個隊列,這時隊列中的消息會被平均分攤(輪詢)給多個消費者進行消費,而不是每一個消費者都收到全部的消息進行消費
RabbitMQ四種類型的交換器
direct交換器,fanout交換器,topic交換器,headers交換器ui
direct交換器
把消息路由到RoutingKey與BindingKey徹底匹配的隊列中,是徹底匹配、單播的形式spa
- eg:若是路由鍵爲「java」,則只能轉發RoutingKey爲「java」的消息到綁定的隊列中去,不會轉發如「java.spring」
fanout交換器
會把發送到該交換器的消息路由到全部與該交換器綁定的隊列中,不會匹配路由Key,轉發消息是最快的代理
topic交換器
經過模式匹配分配消息,將路由鍵和某個模式進行匹配,識別兩個通配符:「#」和「」。#匹配0個或多個單詞,匹配一個單詞code
- eg:發送一條消息,RoutingKey爲「java.spring」,這時候會匹配到RoutingKey爲「java.#」和「#.spring」的隊列
headers交換器
不依賴於路由鍵的匹配規則來路由消息,而是根據發送的消息內容中的headers 屬性進行匹配。該交換器類型性能較差且不實用,所以通常不會用到對象