消息中間件-RabbitMQ學習筆記

原文鏈接:https://ke.qq.com/course/422865?taid=3628998257439697

消息中間件定義:

消息中間件利用高效可靠的消息傳遞機制進行平臺無關的數據交流,並基於數據通信來進行分佈式系統的集成。通過提供消息傳遞和消息排隊模型,它可以在分佈式環境下擴展進程間的通信。

爲什麼要用消息中間件:

異步操作可以提高業務系統的響應速度提高用戶體驗;可以和業務系統解耦提高使業務功能更內聚;可以應對高峯訪問避免業務高峯時期的宕機造成系統不可用;以上總的來說就是MQ的優點:異步、解耦、削峯。

使用消息中間件的不足之處:

1、系統複雜度提高;2系統可用性降低,增大了業務失敗的風險;3、加大了保持一致性的難度。

常用的消息中間件介紹和對比:

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什麼優缺點?

特性 ActiveMQ RabbitMQ RocketMQ Kafka
單機吞吐量 萬級,比 RocketMQ、Kafka 低一個數量級 同 ActiveMQ 10 萬級,支撐高吞吐 10 萬級,高吞吐,一般配合大數據類的系統來進行實時數據計算、日誌採集等場景
topic 數量對吞吐量的影響     topic 可以達到幾百/幾千的級別,吞吐量會有較小幅度的下降,這是 RocketMQ 的一大優勢,在同等機器下,可以支撐大量的 topic topic 從幾十到幾百個時候,吞吐量會大幅度下降,在同等機器下,Kafka 儘量保證 topic 數量不要過多,如果要支撐大規模的 topic,需要增加更多的機器資源
時效性 ms 級 微秒級,這是 RabbitMQ 的一大特點,延遲最低 ms 級 延遲在 ms 級以內
可用性 高,基於主從架構實現高可用 同 ActiveMQ 非常高,分佈式架構 非常高,分佈式,一個數據多個副本,少數機器宕機,不會丟失數據,不會導致不可用
消息可靠性 有較低的概率丟失數據 基本不丟 經過參數優化配置,可以做到 0 丟失 同 RocketMQ
功能支持 MQ 領域的功能極其完備 基於 erlang 開發,併發能力很強,性能極好,延時很低 MQ 功能較爲完善,還是分佈式的,擴展性好 功能較爲簡單,主要支持簡單的 MQ 功能,在大數據領域的實時計算以及日誌採集被大規模使用

ActiveMQ:apache出品,能力強勁的開源消息總線,完全支持jms規範的消息中間件。api豐富,在傳統行業的中小
型企業中應用廣泛。缺點:服務性能和數據存儲性能不好。
kafka:apache頂級項目,追求高吞吐量。一開始的目的是用於日誌收集和傳輸。不支持事務,對消息重複,丟失,
錯誤沒有嚴格的要求。適合產生大量數據的互聯網服務的數據收集業務。
rocketMQ:阿里開源中間件,目前已經孵化爲apache頂級項目,純java開發。思路起源於kafka,對消息的可靠性
傳輸和事務性做了優化。特點:高吞吐量,高可用,適合大規模分佈式系統應用。目前在阿里集團被廣泛使用,用於
交易,充值,流計算,日誌處理,消息推送等。
高性能,高可靠性,支持分佈式,支持事務,集羣水平的擴展,上億級別消息的堆積,主從之間的自由切換等表現良
好,但是商業版收費。很多功能不對外公佈。

消息中間件最實踐:

小型公司,技術實力較爲一般,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,用 RocketMQ 是很好的選擇。如果是大數據領域的實時計算、日誌採集等場景,用 Kafka 是業內標準的,絕對沒問題,社區活躍度很高,絕對不會黃,何況幾乎是全世界這個領域的事實性規範。

以上是對消息中間件的大概介紹。下面是對RabbitMQ學習的記錄,

RabbitMQ採用Erlang語言書寫的, 該語言最早用於交換機編程,主要優點就是做數據轉換,所以使用RabbitMQ的優點是系統延遲比較小。開源,性能優秀,提供可靠性消息投遞模式,返回模式與springAMQP完美的整合
集羣模式豐富,表達式配置,HA模式,鏡像隊列模型。1. Erlang語言最初用於交換機領域,這樣使RabbitMQ在Broker之間進行數據交互的性能是非常優秀的。2. Erlang有着和原生Socket一樣的延遲。

什麼是AMQP協議

高級消息隊列協議Advanced Message Queuing Protocol
是具有現代特徵的二進制協議。是一個提供統一消息服務的的應用層標準高級消息隊列協議,是應用層協議的一個開
放標準,爲面向消息的中間件設計。
是一個規範,裏面有很多的概念,我們開發的時候按着他這個標準走就可以了.

AMQP核心概念

生產者把消息交給服務器,服務器裏面有虛擬主機,主機裏面有ampq的核心exchange交換機。生產者需要有服務器
的ip和端口號,找到服務器,服務器需要把消息投遞到哪個虛擬主機上。接下來,虛擬主機把消息交給交換機。我們
的rabbitMq就是用來解耦了,做到這裏,消息的生產者的任務就做完了。
rabbitMQ會把消息交給消費者。消費者會監聽消息隊列message queue。交換機和消息隊列會進行綁定。
具體的概念:
1. server:又稱broker,接受客戶端的鏈接,實現amqp實體服務。
2. Connection:鏈接,應用程序跟broker的網絡鏈接。
3. channel:網絡信道,幾乎所有的操作都是在channel中進行。數據的流轉都要在channel上進行。channel是進
行消息讀寫的通道。客戶端可以建立多個channel,每個channel代表一個會話任務。
4. message:消息,服務器與應用程序之間傳送的數據,由Properties和body組成。Properties可以對消息進行
修飾,比如消息的優先級,延遲等高級特性。body則就是消息體的內容。
5. virtual host:虛擬地址,用於進行邏輯隔離,最上層的消息路由。一個虛擬地址裏面可以有多個交換機
exchange和消息隊列message queue。
6. exchange:交換機,接收消息,根據路由機轉發消息到綁定的隊列。
7. binding:綁定。交換機和隊列之間的虛擬鏈接。綁定中可以包含routing key。
8. routing key:一個路由規則,虛擬機可以用它來確定如何路由一個特定消息。
9. queue:消息隊列,保存消息並將它們轉發給消費者。

AMQP消息如何流轉

生產者生產出消息,投遞到交換機上,一個交換機可以綁定多個消息隊列。
爲什麼只有一個消息隊列中有消息?
交換機接收到消息後會根據路由規則找到指定的消息隊列。所以生產者生產消息時需要指定消息的routing key。交
換機會把消息交給消息隊列。消費者就可以監聽消息隊列,從消息隊列中獲取消息。

RabbitMQ安裝和使用

1. 安裝linux必要依賴包。
2. 官網下載rabbitMQ的安裝包,先安裝erlang。
3. 下載rabbitMQ的必須安裝包。
4. 配置rabbitMQ。
核心配置文件rabbit.app可以看到默認的端口號是5672.
lookback_users的用戶名[guest]
ctl:控制相關的命令
plugins:插件管理
server:啓停服務
啓動rabbitMQ
rabbitmq-server start &
啓動時如果發生提示已經啓動需要手動kill進程
ps -ef | grep rabbit
啓動後可以通過lsof -i:5672查看啓動進程
停止rabbitMQ服務
rabbitmqctl stop_app
管理插件:rabbitmq-plugins list可以查看現在的插件列表
啓動管控臺:rabbitmq-plugins enable rabbitmq_management
訪問地址:http://ip:15672
訪問前可以關閉防火牆:systemctl stop firewalld

命令行和圖形化控制檯

基礎操作:
1. rabbitmqctl stop_app 關閉應用
2. rabbitmqctl start_app 啓動應用
3. rabbitmqctl status 查看節點狀態
4. rabbitmqctl add_user username password 添加用戶
5. rabbitmqctl list_users 列出所有用戶
6. rabbitmqctl delete_user username 刪除用戶
7. rabbitmqctl clear_permissions -p vhostpath username 清除用戶權限
8. rabbitmqctl reset 移除所有數據,要在rabbitmqctl stop_app之後使用
9. rabbitmqctl list_queues 列出所有的消息隊列
10. rabbitmqctl list_exchanges 列出所有的交換機
控制檯:
交換機頁面的介紹
演示添加虛擬主機,給虛擬主機指定用戶操作。
管控臺可以操作的界面ctl都可以通過命令操作。
介紹管控臺的概覽。

消息的生產和消費

ConnectionFactory:獲取連接的工廠
Connection:一個客戶端和server的連接
Channel:數據通信信道,可以發送和接受消息
Queue:具體的消息存儲隊列
QueuingConsumer:消息隊列的消費者
Delivery:mq對消息和channel的java封裝
消息的生產者代碼:

public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory=new ConnectionFactory();
消息的消費者代碼:
交換機詳解
exchange:接收消息,並根據路由鍵轉發消息所綁定的隊列。
交換機的屬性:
factory.setHost("192.168.157.128");
factory.setPort(5672);
factory.setVirtualHost("/");
Connection conn = factory.newConnection();
Channel channel=conn.createChannel();
for(int i=0;i<5;i++){
String body="hello rabbitmq!";
//第一個參數是交換機的名稱,爲空表示使用默認交換機,第二個參數表示路由鍵,第三個參數表示消息的
屬性。最後表示消息的內容
channel.basicPublish("","test001",null,body.getBytes());
}
channel.close();
conn.close();
}


消息的消費者代碼:

ConnectionFactory factory=new ConnectionFactory();
factory.setHost("192.168.157.128");
factory.setPort(5672);
factory.setVirtualHost("/");
Connection conn = factory.newConnection();
Channel channel=conn.createChannel();
String queueName="test001";
//聲明隊列
//第一個參數是隊列的名稱,第二個參數表示是否持久化消息隊列,第三個參數表示channel獨佔,包裝順序的消費。
// 第四個參數表示是否自動刪除。當隊列沒有綁定交換機就自動刪除。第五個參數是擴展參數
channel.queueDeclare(queueName,true,false,false,null);
//創建消費者
QueueingConsumer consumer = new QueueingConsumer(channel);
//設置channel,
/*
第一個參數是隊列名.第二個參數表示ack消息是否自動簽收,第三個是消費者對象
*/
channel.basicConsume(queueName,true,consumer);
//獲取消息
while(true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message=new String(delivery.getBody());
System.out.println("消費端:"+message);
}


交換機詳解
exchange:接收消息,並根據路由鍵轉發消息所綁定的隊列。
name:交換機的名稱
type:交換機的類型direct,topic,fanout,headers
durability:是否需要持久化,true爲持久化。
auto delete:當最後一個綁定到exchange上的隊列刪除後,自動刪除該exchange。
internal:當前exchange是否用於rabbitMQ內部使用,默認爲false。
arguments:可擴展參數。用戶自自定義的交換機時,用到的參數。

交換機的類型

topic:
1. 所有發送到topic exchange的消息被轉發到所有關心RouteKey的Queue上
2. Exchange將RouteKey和某些隊列進行模糊匹配,此時隊列需要綁定一個Topic
模糊匹配可以使用通配符:
#可以匹配一個或多個詞
*只能匹配一個詞
比如:"log.#"可以匹配到“log.info.oa”。“log.*”只會匹配到“log.error”

Fanout:
1. 不處理路由鍵,只需要簡單的將隊列綁定到交換機上。
2. 發送到交換機的消息都會被轉發到與該交換機綁定的所有隊列上
3. fanout交換機轉發消息是最快的。

隊列,綁定,虛擬主機,消息

綁定:交換機跟隊列的連接關係,兩個交換機的連接關係。包含routing key
消息隊列:實際存儲消息數據的。
durability:是否持久化
auto_delete:當最後一個監聽被移除之後,該隊列是否被自動刪除。
消息:服務器和應用之間傳遞的數據。有properties和payload(body)組成。
消息的常見屬性:
delivery mode:送達模式,是否持久化
headers:自定義消息屬性,消息裏面有常規的一些屬性,一些特別的屬性需要在headers裏面進行定義
content_type:消息內容的類型
content_encoding:編碼集
priority:優先級,從0-9,數字越大優先級越高
虛擬主機:用於進行邏輯隔離,最上層的消息路由。一個虛擬主機裏面可以有若干個交換機和消息隊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章