RabbitMQ 常用命令
- 設置文件夾結構(日志文件夾,數據庫文件夾 - 存儲服務器信息,比如元數據、虛擬主機等)
$ mkdir -p /var/log/rabbitmq
$ mkdir -p /var/lib/rabbitmq/mnesia/rabbit
- 啟動 - 生產環(huán)境運行
RabbitMQ時,通常建一個rabbitmq用戶,為其賦予文件夾權限,而非使用普通用戶賬戶來運行所有命令。
$ ./sbin/rabbitmq-server
- 查看服務器狀態(tài)
$ ./sbin/rabbitmqctl status
-
vhost和權限控制無法通過AMQP協議創(chuàng)建(不同于交換器,隊列和綁定),需要通過./sbin/目錄中的rabbitmqctl工具來創(chuàng)建
遠程控制方法: 通過指定-n rabbit@[server_name]來管理遠程RabbitMQ節(jié)點,@左邊是Erlang應用程序名稱,這里永遠是rabbit,右邊是服務器主機名或者IP地址。**需要確保運行Rabbit節(jié)點的服務器和運行rabbitmqctl的工作站安裝了相同的Erlang cookie
// 1. 創(chuàng)建虛擬機
$ ./sbin/rabbitmqctl add_vhost [vhost_name]
// 2. 刪除虛擬機
$ ./sbin/rabbitmqctl delete_vhost [vhost_name]
// 3. 查看虛擬機
$ ./sbin/rabbitmqctl list_vhosts
- 重要概念
vhost: 本質上是一個mini版的RabbitMQ服務器,擁有自己的交換器、綁定、隊列...,更重要的是,它擁有自己的權限控制。這使得你能夠安全地使用一個RabbitMQ服務器來服務眾多應用程序,而不用擔心別人刪除你的隊列,不用擔心隊列、交換器的命名沖突,有利于集群部署。
vhost之于Rabbit就像是虛擬機之于物理服務器一樣:它們通過在各個實例間提供邏輯上的分離,允許你為不同的應用程序安全保密的運行數據。- 消費者對消息的確認和告訴生產者消息已經被接收了這兩件事情毫不相關
消費者通過確認命令告訴RabbitMQ它已經正確的接收了消息,同時RabbitMQ才能安全的把消息從隊列刪除- 消費者和生產者都能通過
queue.declare命令來創(chuàng)建隊列,但如果消費者在同一條信道上訂閱了另一個隊列的話,就無法再聲明隊列了。必須先取消訂閱,將信道置為傳輸模式- 隊列設置中一些有用的參數
exclusive(獨占的):如果設置為true,隊列將變?yōu)樗接械?,此時只有你的應用程序才能消費隊列消息,當你想要限制一個隊列只有一個消費者的時候很有幫助auto-delete:當最后一個消費者取消訂閱的時候,隊列就會自動刪除,如果你需要臨時隊列只為一個消費者服務的話,請結合使用auto-delete和exclusive。當消費者斷開連接時,隊列就被移除了
basic.reject允許消費者拒絕RabbitMQ發(fā)送的消息,如果把reject命令的requeue參數設置為true的話,RabbitMQ會將消息發(fā)送給下一個訂閱的消費者,如果設置為false的話,RabbitMQ立即會把消息從隊列中移除。dead letter死信隊列:用來存放那些被拒絕而不重入隊列的消息,需要使用reject命令并將requeue參數設置為false。死信隊列讓你通過檢測 (拒絕 / 未送達) 的消息來發(fā)現問題

交換器、綁定、隊列的關系圖
QA:
1. 如果聲明一個已經存在的隊列會發(fā)生什么?
如果聲明參數完全匹配現存隊列,
Rabbit就什么也不做,并成功返回。如果參數不匹配的話,隊列聲明嘗試會失敗,如果只是想檢測隊列是否存在,則可以設置queue.declare的passive(被動的) 為true。在該設置下,如果隊列存在,那么queue.declare命令會成功返回;如果隊列不存在,queue.declare命令也不會創(chuàng)建隊列,而會返回一個錯誤。
2. 由生產者還是消費者來創(chuàng)建隊列?
消費者才需要訂閱隊列,但是還要考慮生產者能否承擔得起丟失消息。發(fā)送出去的消息如果路由到了不存在的隊列的話,
Rabbit會忽略它們。如果不能承擔消息丟失,最好生產者和消費者都嘗試去創(chuàng)建隊列
3. 如何保證消息的持久化?
必須設置成如下:
delivery mode(投遞模式)必須設置為2(persistent)持久化, 2 是非持久化(non-persistent)- 發(fā)送到持久化的交換器
- 到大持久化的隊列
4. 持久化原理?
先將消息寫入磁盤上的一個持久化文件。當發(fā)布一條持久性消息到持久化交換器上時,
Rabbit會把消息寫入到日志文件后才發(fā)送響應。注意:如果之后這條消息路由到了非持久化隊列,它會自動從持久性日志中移除,并且無法從服務器重啟中恢復。 一旦從持久化隊列中消費了一條持久性消息(并且手動確認了它),Rabbit在持久性日志中把這條消息標記為等待垃圾收集。
一. direct 交換器:如果路由鍵匹配的話,消息就被投遞到對應的隊列

image.png
二. fanout 交換器:當發(fā)送一條消息到 fanout 交換器時,它會把消息投遞給所有附加在此交換器上的隊列

image.png
應用場景:舉例來說,一個
web 應用程序可能需要在用戶上傳圖片時,用戶相冊必須清除緩存,同時用戶應該得到積分獎勵。你可以將兩個隊列綁定到圖片上傳交換器上。一個用于清除緩存,一個用戶增加用戶積分。當有新需求需要添加其他規(guī)則時,只要為新的消費者寫一段代碼,然后聲明新的隊列并將其綁定到 fanout交換器上即可,而不用修改原來的代碼。
三. topic 交換器:

topic交換器消息流