消息代理(Message Broker): 一種消息驗證、傳輸、路由的架構模式,實現應用程序之間消息傳遞的解耦
RabbitMQ:實現高級消息隊列協議(AMQP)的開源消息代理中間件
AMQP特性:消息方向、消息隊列、消息路由(PTP/SB)、可靠性、安全性
1. RabbitMQ基本概念:
- Broker:消息隊列服務器的實體,負責接收生產者的消息,然後將消息發送到消息接收者或者其他Broker
- Exchange:消息交換機,消息第一個到達的地方,消息通過它指定的路由規則,分發到不同的消息隊列(類似路由器)
- Queue:消息隊列:消息通過發送和路由之後達到的地方,到達Queue的消息即進入邏輯上的等待消費狀態,每個消息都會發送到一個或多個隊列。
- Binding:綁定:將Exchange和Queue按照路由規則綁定起來,是Exchange\Queue的虛擬連接
- Routing Key:路由關鍵字,Exchange根據關鍵字進行消息投遞
- Virtual host:虛擬主機,對Broker進行虛擬劃分,將消費者、生產者和依賴的AMQP相關結構進行隔離,一個Broker可設置多個虛擬主機,對不同的用戶進行權限隔離。
- Connection:連接,代表生產者、消費者、Broker之間進行通信的物理網絡
- Channel:消息通道,用於連接生產者、消費者的邏輯結構,每個連接可創建多個Channel,每個channel標識一個會話任務,通過channel可隔離同一連接不同的交互內容
- Producer:消息生產者,製造消息併發送消息的程序
- Consumer:消息消費者,接收消息並處理消息的程序
2. 消息投遞過程:
- 客戶端連接到消息隊列服務器,打開channel
- 客戶端聲明Exchange,設置屬性
- 客戶端聲明Queue,設置屬性
- 客戶端使用Routing Key,在Exchange和Queue之間建立綁定關係
- 客戶端投遞消息到Exchange
- Exchange接收消息後根據消息的key和已設置的Binding,進行消息路由,將消息投遞到Queue
3.Exchange類型:
- Direct交換機:完全按照Key進行投遞
- Topic交換機:對Key進行模式匹配後進行投遞: *匹配一個詞,#匹配一個或多個詞
- Fanout交換機:不需要key,通過廣播模式,將消息投遞到該交換機綁定的所有隊列
- Headers交換機: 根據消息頭部決定隊列消息分發
消息確認模式:
- Nack message requeue true: 消息確認後是否可重新入隊,重新入隊消息可重複處理
- Ack message requeue false: 消息確認後不可重新入隊,避免消息重複消費
- Reject requeue true: 消息被拒絕,可重新入隊
- Reject requeue false: 消息被拒絕,不可重新入隊,消息進入死信隊列或被丟棄
4. RabbitMQ特性:持久化
- Exchange持久化:聲明時指定durable=>1
- Queue持久化:聲明時指定durable=>1
- 消息持久化:投遞時指定delivery_mode=>2 (1:非持久化)
注意:若Exchange和Queue都持久化,那麼Binding也是持久化的,如果Exchange和Queue有一個是非持久化,那麼不允許建立綁定
5. rabbit相關命令
5.1 啓/停RabbitMQ
啓動RabbitMQ服務器:
- 前臺啓動RabbitMQ服務器: rabbitmq-server start
- 後臺啓動RabbitMQ服務器: rabbitmq-server -detached (類似shell後臺執行命令)
啓/停應用:
- rabbitmqctl.bat stop_app
- rabbitmqctl.bat start_app
啓用WEB管理工具
- rabbitmq-plugins enable rabbitmq_management
- WEB訪問頁面:http://localhost:15672 默認用戶:guest/guest 注意:RabbitMQ管理工具啓用之後,RabbitMQ必須重啓,否則無法生效
5.2 用戶命令
用戶管理基本命令:
- 添加用戶:rabbitmqctl add_user <username> <password>
- 刪除用戶:rabbitmqctl delete_user <username>
- 修改用戶密碼:rabbitmqctl change_password <username> <newpassword>
- 刪除密碼:rabbitmqctl clear_password <username>
- 設置用戶角色:rabbitmqctl set_user_tags <username> <tag> 執行命令時會清空原有角色,角色可以設置多個或零個;
- 查詢所有用戶名:rabbitmqctl list_users
- 用戶授權(管理員):rabbitmqctl set_user_tags 用戶名 administrator
rabbitmq:新增遠程訪問用戶:
- 創建用戶:rabbitmqctl add_user 用戶名 登陸密碼
- 分配角色:rabbitmqctl set_user_tags 用戶名 administrator
- 授權: rabbitmqctl set_permissions -p "/" 用戶名 "." "." ".*"
5.3 其他常用命令:
- 打印消息隊列列表:rabbitmqctl list_queues [-p <vhostpath>] [<queueinfoitem> ...]
- 打印交換機列表:rabbitmqctl list_exchanges [-p <vhostpath>] [<exchangeinfoitem> ...]
- 打印綁定器列表:rabbitmqctl list_bindings [-p <vhostpath>] [<bindinginfoitem> ...]
- 打印連接列表: rabbitmqctl list_connections [<connectioninfoitem> ...]
- 打印消費者列表: rabbitmqctl list_channels [<channelinfoitem> ...]
6. 用戶角色
RabbitMQ用戶角色: none、management、policymaker、monitoring、administrator
none: 不能訪問 management plugin
management
- 用戶可以通過AMQP做的任何事外加:
- 列出自己可以通過AMQP登入的virtual hosts
- 查看自己的virtual hosts中的queues, exchanges 和 bindings
- 查看和關閉自己的channels 和 connections
- 查看有關自己的virtual hosts的“全局”的統計信息,包含其他用戶在這些virtual hosts中的活動
policymaker
- management可以做的任何事外加:
- 查看、創建和刪除自己的virtual hosts所屬的policies和parameters
monitoring
- management可以做的任何事外加:
- 列出所有virtual hosts,包括他們不能登錄的virtual hosts
- 查看其他用戶的connections和channels
- 查看節點級別的數據如clustering和memory使用情況
- 查看真正的關於所有virtual hosts的全局的統計信息
administrator
- policymaker和monitoring可以做的任何事外加:
- 創建和刪除virtual hosts
- 查看、創建和刪除users
- 查看創建和刪除permissions
- 關閉其他用戶的connections
指定授權:rabbitmqctl set_permissions -p / 用戶名 "." "." ".*"
補充說明: "*"分別表示:配置、寫、讀權限
7. 集羣架構
7.1 主備模式(Warren)
說明:主節點提供消息讀寫服務,備用節點不負責消息讀寫處理,若主節點故障備用節點自動切換爲主節點提供服務(HaProxy)
場景:併發、數據量不高
HaProxy配置:
listen rabbitmq_cluster
bind 0.0.0.0:5672
mode tcp #配置TCP模式
balance roundrobin #簡單的輪詢
server bhz76 192.168.11.12:5672 check inter 5000 rise 2 fall 3 #主節點
server bhz77 192.168.11.13:5672 backup check inter 5000 rise 2 fall 3 #備用節點
說明:間隔5s檢查健康1次,2次正常表示MQ節點正常,3次故障表示節點故障 backup: 表示備用節點
7.2 遠程模式(Shovel: 不常用)
說明:可以將消息進行不同數據中心複製工作,可以實現跨區域的MQ集羣互聯
模型:近端同步確認、遠端異步確認
特點:雙活,另外當MQ集羣處理到達到瓶頸,新到來的消息可以轉發到另外1個區域的MQ集羣處理,提高消息處理速度
7.3 鏡像模式(實際使用)
說明:MQ節點之間互相實現消息同步,可確保數據100%不丟失,每個集羣節點數據完全一致
7.4 多活模式
說明:實現異地數據複製的主流模式,需藉助Federation插件實現不同集羣隊列消息共享,避免單集羣故障導致整體系統故障
8. 問題場景
8.1 保證消息不丟失解決方案
生產者丟失數據:消息發送過程中因網絡問題發送失敗 方案:事務發送消息(同步阻塞:性能慢)、開啓confirm模式(異步:推薦)
MQ丟失數據:MQ未持久化或者還未完成持久化,故障導致數據丟失 方案:創建Queue持久化 + 發送消息持久化(deliveryMode=2),該模式下只有消息完成持久化纔會回調confirm關聯接口
消費者丟失數據:消費者剛消費到,但未處理消費者故障 方案:關閉消費者自動提交ack,消息完全消費完後手動提交