RabbitMQ是一個開源的AMQP實現,服務器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用於在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。
它是一個很強的消息隊列,是個中間件。
## 安裝rabbitmq # 安裝依賴 yum install gcc glibc-devel make ncurses-devel openssl-devel xmlto # 安裝或更新EPEL庫 yum -y install epel-release # 或: wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -ivh epel-release-6-8.noarch.rpm # 安裝erlang 下載 https://bintray.com/rabbitmq/rpm/erlang # 注意el6 和 el7的區別 rpm -ivh erlang-21.1.2-1.el6.x86_64.rpm # centos6.5用el6 ## 檢查 erl # 進入erlang 出現:Erlang/OTP 21 [erts-10.1.2] [source] [64-bit]... halt(). # 退出 erlang netstat -nltp # 端口4369即是erlang的進程 # 安裝MQ 下載 # http://www.rabbitmq.com/download.html rpm -ivh rabbitmq-server-3.7.11-1.el6.noarch.rpm
如果是CentOS7以上,安裝時會稍有不同,除了注意版本的選擇外,可能還需要安裝依賴:
yum -y install socat
並且安裝了erlang后,進程中看不到4369端口打開,但是當啟動rabbitmq-server時,erlang會一起啟動。
systemctl start rabbitmq-server
簡單的服務啟動與停止
## 服務管理命令 service rabbitmq-server start # 啟動 service rabbitmq-server status # 狀態 service rabbitmq-server stop # 停止 rabbitmq-plugins enable rabbitmq_management # 啟用15672 web管理
# 如果執行這條命令,會在/etc/rabbitmq/ 下生成 文件 enabled_plugins
## 常用命令 rabbitmqctl # 幫助 rabbitmqctl status # 狀態 同上 rabbitmqctl stop # 停止服務 會將節點及應用程序同時關閉 # 由於同一節點可能運行除rabbitmq 其他erlang程序,停止整個節點是不可取的 rabbitmqctl stop_app # 保持25672不停 rabbitmqctl start_app # 啟動5672 和 15672
# 3.7.11 默認情況下guest用戶只能localhost訪問。可以添加賬號用於遠程登錄,或者啟用guest遠程。
## 用戶管理 rabbitmqctl add_user admin 123456 # 添加用戶admin rabbitmqctl delete_user admin # 刪除用戶 rabbitmqctl change_password admin 111111 # 修改密碼 rabbitmqctl list_users # 查看用戶列表 rabbitmqctl set_permissions -p / admin ".*" ".*" ".*" # 賦予訪問 / 權限 rabbitmqctl set_user_tags admin administrator # 賦予管理員權限
cp /usr/share/doc/rabbitmq-server-3.7.11/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
# 復制個配置文件到此后,修改內容:
{loopback_users, []}, # 去掉此行前面的 %% 即啟用此配置(最后面的逗號可能要去掉)
# 重啟服務后,guest即可遠程登錄
service rabbitmq-server restart
## 用戶角色 參考:
鏈接:https://www.jianshu.com/p/e3af4cf97820
用戶角色可分為五類,超級管理員, 監控者, 策略制定者, 普通管理者以及其他。
(1) 超級管理員(administrator)
可登陸管理控制台(啟用management plugin的情況下),可查看所有的信息,並且可以對用戶,策略(policy)進行操作。
(2) 監控者(monitoring)
可登陸管理控制台(啟用management plugin的情況下),同時可以查看rabbitmq節點的相關信息(進程數,內存使用情況,磁盤使用情況等)
(3) 策略制定者(policymaker)
可登陸管理控制台(啟用management plugin的情況下), 同時可以對policy進行管理。但無法查看節點的相關信息(上圖紅框標識的部分)。與administrator的對比,administrator能看到這些內容。
(4) 普通管理者(management)
僅可登陸管理控制台(啟用management plugin的情況下),無法看到節點信息,也無法對策略進行管理。
(5) 其他
無法登陸管理控制台,通常就是普通的生產者和消費者。
## 以下博客都對操作RabbitMQ有詳細介紹。
# springboot操作RabbitMQ使用參考:https://www.cnblogs.com/ityouknow/p/6120544.html
# C# 操作RabbitMQ使用參考: https://www.cnblogs.com/richieyang/p/5492432.html
# Node.js操作RabbitMQ https://www.cnblogs.com/wukong-holmes/p/9306733.html
升級
有一台CentOS7.5 Erlang 和 rabbitmq-server 都已經版本過低,官方已經不再支持。
升級時直接准備好 rpm 和 配置文件,然后寫個批處理執行,完成。缺點是沒有對數據備份,會有短暫的丟失。
在/opt/下放入文件:
rabbitmq-server-3.7.15-1.el7.noarch.rpm erlang-21.3.8.4-1.el7.x86_64.rpm
原有的/etc/rabbitmq/下的配置文件可以繼續使用,新版本在啟動服務時,會自動讀取原有配置文件。
也可根據實際需求修改,如果沒有,也可添加文件:
rabbitmq.config
[
{rabbit, [{log_levels, [{channel, warning}, {connection, warning}, {federation, warning}, {mirroring, warning}]},
{loopback_users, []}
]}
].
enabled_plugins
[rabbitmq_management,rabbitmq_top].
rabbitmq-env.conf
RABBITMQ_LOG_BASE=/db/logs/rabbitmq
使用 rpm -qa |grep erlang 以及 rpm -qa |grep rabbitmq 列出舊的軟件名稱,然后加入批處理中卸載。
使用 netstat -nltp 找出4369端口的 PID ,加入批處理中 kill
最后執行批處理:
systemctl stop rabbitmq-server kill -9 24593 # erlang 4369 rpm -e --nodeps erlang-test_server-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-erts-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-mnesia-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-xmerl-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-inets-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosEvent-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-edoc-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-tv-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosEventDomain-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-eldap-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-ic-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-eunit-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-webtool-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-debugger-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-reltool-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-typer-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-crypto-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-syntax_tools-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-runtime_tools-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-asn1-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-orber-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosTime-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-ssh-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-os_mon-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosTransactions-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-diameter-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-observer-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-megaco-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-dialyzer-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-kernel-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-compiler-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-gs-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-public_key-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-tools-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosNotification-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-otp_mibs-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-erl_docgen-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-appmon-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-toolbar-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-jinterface-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-wx-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-common_test-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-stdlib-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-hipe-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-snmp-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-ssl-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-sasl-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosProperty-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-pman-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-cosFileTransfer-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-percept-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-erl_interface-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-parsetools-R16B-03.18.el7.x86_64 rpm -e --nodeps erlang-et-R16B-03.18.el7.x86_64 rpm -e --nodeps rabbitmq-server-3.3.5-34.el7.noarch cd /opt rpm -Uvh erlang-21.3.8.4-1.el7.x86_64.rpm rpm -Uvh rabbitmq-server-3.7.15-1.el7.noarch.rpm systemctl start rabbitmq-server rabbitmqctl change_password guest oldpwd rabbitmq-plugins enable rabbitmq_management
登錄相應的 http 地址,使用舊密碼登錄,檢查exchage和queue等。 因為批處理里自動改了舊密碼,所以,原有的應用程序可直接訪問 rabbitmq-server
更新:
centos7
# 下載導入 key rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc yum install rabbitmq-server-3.8.1-1.el7.noarch.rpm #-------------------------- rpm 方式,方便快速 ------------------------- # https://www.rabbitmq.com/install-rpm.html # 1. 下載並安裝 erlang 找到版本對應的RPM包 # 版本需求:https://www.rabbitmq.com/which-erlang.html # 下載地址:https://bintray.com/rabbitmq-erlang/rpm/erlang yum -y install socat rpm -Uvh erlang-22.1.7-1.el7.x86_64.rpm rpm -ivh rabbitmq-server-3.8.1-1.el7.noarch.rpm ## service systemctl status rabbitmq-server systemctl start rabbitmq-server systemctl stop rabbitmq-server systemctl restart rabbitmq-server ## 啟用 管理 插件 rabbitmq-plugins enable rabbitmq_management # 啟用web 15672 # rabbitmq_delayed_message_exchange-3.8.0.ez # 下載.ez文件至 /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.1/plugins/ rabbitmq-plugins list # 啟用 rabbitmq-plugins enable rabbitmq_delayed_message_exchange # 在管理界面中, Add a new exchange, 查看Type中有無類型 x-delayed-message rabbitmqctl status # 狀態 rabbitmqctl start_app # 啟動應用 rabbitmqctl stop_app # 停止應用 ## 用戶管理 也可以在 web 控制台里操作。 rabbitmqctl add_user admin 123456 # 添加用戶admin rabbitmqctl set_permissions -p / admin ".*" ".*" ".*" # 賦予訪問 / 權限 rabbitmqctl set_user_tags admin administrator # 賦予管理員權限 rabbitmqctl delete_user admin # 刪除用戶 rabbitmqctl change_password admin 111111 # 修改密碼 rabbitmqctl list_users # 查看用戶列表 cp /usr/share/doc/rabbitmq-server-3.7.11/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config # 復制個配置文件到此后,修改內容: {loopback_users, []}, # 去掉此行前面的 %% 即啟用此配置(最后面的逗號可能要去掉) # 重啟服務后,guest即可遠程登錄 service rabbitmq-server restart rabbitmqctl list_queues --vhost test # 某vhost下所有隊列名 rabbitmqctl list_queues --vhost test messages_ready messages_unacknowledged #-------------------- config file -------------------------------------- # 3.7.0之后推薦使用 key = value 格式。 listeners.tcp.default = 5673 #---------------------- cluster 1 simple ------------------------------ # 統一各主機的 hosts 文件解析, # 統一各主機的 /var/lib/rabbitmq/.erlang.cookie 文件內容相同 systemctl restart rabbitmq-server.service # 全部重啟服務 # 次要主機 rbtmq02 操作如下: rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rbtmq01 rabbitmqctl cluster_status # 特點: # 1. 聲明隊列時的節點,后續不變。除非刪除隊列。 # 2. 節點沒有的數據,會從其它節點讀取。 # 普通模式:默認模式,以兩個節點AB為例說明。對於Queue來說,消息實體只存在於其中一個節點A或B,A和B兩個節點僅有相同的元數據,即隊列的結構。
當消息進入A節點的Queue后,consumer從B節點消費時,RabbitMQ會臨時在A、B間進行消息傳輸,把A中的消息實體取出並經過B發送給consumer。
所以consumer應盡量連接每一個節點,從中取消息。即對於同一個邏輯隊列,要在多個節點建立物理Queue。
否則無論consumer連A或B,出口總在A,會產生瓶頸。當A節點故障后,B節點無法取到A節點中還未消費的消息實體。
如果做了消息持久化,那么得等A節點恢復,然后才可被消費;如果沒有持久化的話,就會產生消息丟失的現象。 # 連接池 # https://pika.readthedocs.io/en/latest/examples/blocking_consume_recover_multiple_hosts.html #---------------------- cluster 2 mirror ------------------------------ # 直接在Admin, Policies, Add/update, 選擇vhost, 填寫Name, # Pattern: 匹配模式. ^ 表示所有; ^ha 表示以 ha 開頭的, # Apply to Exchanges & Queues # 點擊 HA mode, 設置 ha-mode = all 隊列則鏡像到所有的節點。 # 隊列數據鏡像復制之后,如果某一台當機,另一台仍然可用。故障節點恢復后,啟動服務即可。 # 故障期間被消費的數據不會產生重復;新加入的數據在故障節點恢復連接后,將自動同步。 # 鏡像模式:把需要的隊列做成鏡像隊列,存在多個節點。屬於RabbitMQ的HA方案。該模式解決了普通模式中的問題,
不同之處在於,消息實體會主動在鏡像節點間同步,而不是在客戶端取數據時臨時拉取。
該模式帶來的副作用也很明顯,除了降低系統性能外,如果鏡像隊列數量過多,加之大量的消息進入,
集群內部的網絡帶寬將會被這種同步通訊大大消耗掉。所以在對可靠性要求較高的場合中適用。 #------------------------ cluster remove node -------------------------- # 要移除的節點上操作: rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl start_app # 在主節點進行節點的移除. rabbitmqctl forget_cluster_node rabbit@rbtmq02 # 然后查看集群狀態 rabbitmqctl cluster_status #---------------------- 單機啟動3個節點的集群 --------------------------- rabbitmqctl stop RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15672}]" RABBITMQ_NODENAME=rabbit rabbitmq-server -detached RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=rabbit_1 rabbitmq-server -detached RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}]" RABBITMQ_NODENAME=rabbit_2 rabbitmq-server -detached # 加入為 disk rabbitmqctl -n rabbit_1 stop_app rabbitmqctl -n rabbit_1 reset rabbitmqctl -n rabbit_1 join_cluster rabbit rabbitmqctl -n rabbit_1 start_app # 加入為 ram rabbitmqctl -n rabbit_2 stop_app rabbitmqctl -n rabbit_2 reset rabbitmqctl -n rabbit_2 join_cluster rabbit --ram rabbitmqctl -n rabbit_2 start_app #------------------------- Params ------------------------------------ # 連接關閉則 result = channel.queue_declare(queue='', exclusive=True) # ------------------backup & restore -------------------------- # rabbitmqctl eval 'rabbit_mnesia:dir().' cd /var/lib/rabbitmq/mnesia tar zcf rabbit\@rdxmq.tgz rabbit\@rdxmq tar zxf rabbit\@rdxmq.tgz