什麼是RabbitMQ
RabbitMQ是一個開元的AMQP實現,服務端用ERlang語言編寫,支持多種客戶端。用於在分佈式系統中存儲轉發纖細,在易用性、擴展性、高可用性等方面表現不俗
5672,5671
RabbitMQ的用戶角色分類
none、management、policymaker、monitoring、administrator
用戶:
none:
不能訪問management plugin
management:查看和管理自己的信息
用戶可以通過AMQP做的任何事外加:
列出自己可以通過AMQP登入的virtual hosts
查看自己的virtual hosts中的queues,exchange和bindings
查看和關閉自己的channels和connections
查看有關自己的cirtual hosts的“全局”的統計信息,包含其他用戶在這些cirtual hosts中的活動
policymaker:
management基礎上增加
查看、創建和刪除自己的virtual hosts所屬的policies和parameteres
monitoring:查看,監控
management基礎上增加
列出所有virtual hosts,包括他們不能登錄的virtual hosts
查看其他用戶的connections和channels
查看節點級別的數據入clustering和memory使用情況
查看真正的關於所有virtual hosts的全局的統計信息
administrator:管理員權限
policymaker和moniroeing基礎上增加
創建和深處virtual hosts
查看、創建和刪除users
查看創建和刪除permissions
關閉其他用戶的connections
安裝
erlang
https://github.com/rabbitmq/erlang-rpm/releases
yum install -y socat
啓動:systemctl start rabbitmq-server
查看狀態:systemctl status rabbitmq-server
停止服務:systemctl stop rabbitmq-server
開機自啓:systemctl enable rabbitmq-server
開啓插件:rabbitmq-plugins enable rabbitmq_management 說明:rabbitmq有個默認的guest用戶,但只能通過localhost訪問,所以需要添加用戶夠遠程訪問的用戶
添加用戶:rabbitmqctl add_user admin admin
爲用戶分配操作權限:rabbitmqctl set_user_tags admin administrator
爲用戶分配資源權限:rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
開放防火牆端口:firewall-cmd --zone=public --add-port=15672/tcp --permanent
AMQP協議
AMQP(Advanced Message Queueing Protocol)高級消息隊列協議,是應用層協議的一個開放標準爲面向消息的中間件設計
AMQP結構:
AMQP生產者流轉過程:
-->rabbitmq如何發送消息
RabbitMQ中消息發送至Queue時先發送至Exchange(交換機)又Exchange發送至Queue,在Rabbit中一共有4種Exchange
發送消息時不指定Exchange默認使用Queue的名稱直接匹配到對應的Queue,因爲在消息發送時直接指定了Queue
Fanout Exchange: 隊列綁定在Exchange上,當消息發送到交換機上時,Exchange把消息發送至所有綁定在自己身上的Queue
Direct Exchange: 隊列綁定在Exchange上並指定BindKey,Exchange根據BindKey指定發送給符合匹配的Queue
Topic Exchange: 隊列綁定在Exchange上並指定routing key,Exchange根據routing key指定發送給符合匹配的Queue,routing key可以使一個有通配的規則,假如routing key爲“com.#”,那麼所有以“com.”綁定在Exchange上的Queue都將會收到消息
Herders Exchange: 隊列綁定在Exchange上並指定屬性(例x=1),Exchange根據屬性值指定發送給符合匹配的Queue --性能不高,不常用
運轉流程:
高可用
集羣安裝:
在集羣環境中,默認只同步元數據。假如兩個實例做集羣,node1中有數據,node2只同步元數據,數據存在node1中,消費者綁定了node2,
可以看到node2(node1)中的數據,也可以消費node2(node1)的數據。這樣數據在一臺服務器上會有單點故障問題,所以要做高可用方案
元數據包括:
隊列元數據:隊列的名稱及屬性
交換器:交換器的名稱及屬性
綁定關係元數據:交換器與隊列或者交換器與交換器
vhost元數據:爲vhost內的隊列、交換器和綁定提供命名空間及安全屬性之間的綁定關係
高可用方案:
鏡像隊列模式:不僅要同步對象的描述信息,也要同步數據
鏡像隊列模式配置:
可直接在控制檯中配置:
在admin賬戶中選中Admin,選擇Policies(策略)新增策略
選擇該策略名稱,應用範圍(正則),類型(exchange或queue或全部),優先級(數字越大越高),同步的節點數(這條消息同步到幾個節點,推薦三個)
配置完後點擊add policy
持久化
rabbitmq的持久化分爲:隊列持久化、消息持久化和交換器持久化、不管是持久化的消息好事非持久化的消息都可以被寫入到磁盤
隊列持久化:
隊列的持久化是在定義隊列時的durable參數來實現的,durable爲true時,隊列纔會持久化
Connection connection = connectionFactory.newConnection();
Channel channel = connection,createCHannel();
//第二個參數設置爲true,即dutable=true
channel.queueDeclare("queue1",true,false,false,null);
在控制檯中,持久化的隊列在管理界面可以看到有個“D”的標識
消息持久化:
消息持久化通過消息的屬性deliveryMode來設置是否持久化,在發送消息時通過basicPublish的參數傳入
//通過傳入MessageProperties.PERSISTENT_TEXT_PLAIN就可以實現消息持久化
channel.basicPublish("","queue1",MesdsageProperties.PERSISTENT_TEXT_PLAIN,"persistent_test_message".getBytes);
交換器持久化:
同隊列一樣,交換器也需要在定義時設置持久化標識,否則在Broker重啓之後將丟失
//dutrtable爲true則開啓持久化
Exchange.DeclareOk exchangeDeclare(String exchange, String type, boolean durable) throes IOException;
內存控制
當內存使用超過配置的閾值或者磁盤剩餘空間低於配置的閾值時,RabbitMq會暫時阻塞客戶端的連接,並停止接收從客戶端你發來的消息,
以此避免服務崩潰,客戶端與服務端的心跳檢測也會失效,當出現內存告警時,可以通過管理命令臨時調整內存大小,默認內存閾值時0.4
當磁盤剩餘空間低於確定的閾值時,RabbitMQ同樣會阻塞生產者,這樣可以避免因非持久化的消息持續換頁而耗盡磁盤空間導致服務崩潰,
默認情況下,磁盤閾值爲50m,便是當磁盤剩餘空間低於50m時會阻塞生產者並停止內存中消息的換頁動作。一個相對謹慎的做法是將磁盤閾值設置爲
操作系統鎖顯示的內存大小一致
內存換頁:
假如rabbitmq最大佔用內存爲1000m,閾值爲0.5,當存儲的數據大小超過500m時,把內存中的500m數據持久化到磁盤上,釋放內存空間
磁盤控制
與內存控制原理相同,內存分頁之後的數據保存在磁盤上,當擦盤剩餘空間低於預設的值時,磁盤預警
消息可靠性
RabbitM去的消息可靠性,一般是業務系統接入消息中間件是首要考慮的問題,一般通過三個方面保障
發送可靠性:確保消息成功發送到Broker
存儲可靠性:Broker對消息持久化,確保消息不會丟失
消息可靠性:確保消息成功被消費
一般消息發送可靠性分爲三個層級
1、At most once:最多一次,消息可能會丟失,但絕對不會重複傳輸
2、At lwast once:最少一次,消息絕對不會丟失,但可能會重複傳輸
3、Exactly ince:恰好一次,每條消息肯定會被傳輸一次且僅傳輸一次
RabbitMQ支持其中的“最多一次”和“最少一次”,使用中“最多一次”被拋棄,因爲無法確定消息被髮送至MQ中
其中"做少一次"投遞實現需要考慮:
1、消息生產者需要開啓事務機制或者publisher confirm機制,以確保消息可以可靠的傳輸到RabbitMQ中
2、消息生產者需要配合使用mandatory參數或者備份交換器來確保消息能夠從交換器路由到隊列中,進而能夠保存下來而不會被丟棄
消息消費可靠性:
(x-dead-letter-exchange)死信隊列:出現異常或超時的消息保存在死信隊列上
插件機制
rabbitMQ控制檯就屬於插件。
通過插件可以擴展多種核心功能:支持多種協議、系統狀態監控、其它AMQP 0-9-1交換類型、節點聯合等。
許多功能都是通過插件實現的
查看插件列表:
rabbitmq-plugins list
啓用/禁用插件
rabbitmq-plugins enable plugin-name
rabbitmq-plugins disable plugin-name