消息中間件rabbitmq,一般以集群方式部署,主要提供消息的接受和發(fā)送,實(shí)現(xiàn)各微服務(wù)之間的消息異步。本篇將以rabbitmq+HA方式進(jìn)行部署。
一、原理介紹
rabbitmq是依據(jù)erlang的分布式特性(RabbitMQ底層是通過(guò)Erlang架構(gòu)來(lái)實(shí)現(xiàn)的,所以rabbitmqctl會(huì)啟動(dòng)Erlang節(jié)點(diǎn),并基于Erlang節(jié)點(diǎn)來(lái)使用Erlang系統(tǒng)連接RabbitMQ節(jié)點(diǎn),在連接過(guò)程中需要正確的Erlang Cookie和節(jié)點(diǎn)名稱(chēng),Erlang節(jié)點(diǎn)通過(guò)交換Erlang Cookie以獲得認(rèn)證)來(lái)實(shí)現(xiàn)的,所以部署rabbitmq分布式集群時(shí)要先安裝erlang,并把其中一個(gè)服務(wù)的cookie復(fù)制到另外的節(jié)點(diǎn)。
rabbitmq集群中,各個(gè)rabbitmq為對(duì)等節(jié)點(diǎn),即每個(gè)節(jié)點(diǎn)均提供給客戶(hù)端連接,進(jìn)行消息的接收和發(fā)送。節(jié)點(diǎn)分為內(nèi)存節(jié)點(diǎn)和磁盤(pán)節(jié)點(diǎn),一般的,均應(yīng)建立為磁盤(pán)節(jié)點(diǎn),為了防止機(jī)器重啟后的消息消失;
RabbitMQ的Cluster集群模式一般分為兩種,普通模式和鏡像模式。消息隊(duì)列通過(guò)rabbitmq HA鏡像隊(duì)列進(jìn)行消息隊(duì)列實(shí)體復(fù)制。
普通模式下,以?xún)蓚€(gè)節(jié)點(diǎn)(rabbit01、rabbit02)為例來(lái)進(jìn)行說(shuō)明。對(duì)于Queue來(lái)說(shuō),消息實(shí)體只存在于其中一個(gè)節(jié)點(diǎn)rabbit01(或者rabbit02),rabbit01和rabbit02兩個(gè)節(jié)點(diǎn)僅有相同的元數(shù)據(jù),即隊(duì)列的結(jié)構(gòu)。當(dāng)消息進(jìn)入rabbit01節(jié)點(diǎn)的Queue后,consumer從rabbit02節(jié)點(diǎn)消費(fèi)時(shí),RabbitMQ會(huì)臨時(shí)在rabbit01、rabbit02間進(jìn)行消息傳輸,把A中的消息實(shí)體取出并經(jīng)過(guò)B發(fā)送給consumer。所以consumer應(yīng)盡量連接每一個(gè)節(jié)點(diǎn),從中取消息。即對(duì)于同一個(gè)邏輯隊(duì)列,要在多個(gè)節(jié)點(diǎn)建立物理Queue。否則無(wú)論consumer連rabbit01或rabbit02,出口總在rabbit01,會(huì)產(chǎn)生瓶頸。
鏡像模式下,將需要消費(fèi)的隊(duì)列變?yōu)殓R像隊(duì)列,存在于多個(gè)節(jié)點(diǎn),這樣就可以實(shí)現(xiàn)RabbitMQ的HA高可用性。作用就是消息實(shí)體會(huì)主動(dòng)在鏡像節(jié)點(diǎn)之間實(shí)現(xiàn)同步,而不是像普通模式那樣,在consumer消費(fèi)數(shù)據(jù)時(shí)臨時(shí)讀取。缺點(diǎn)就是,集群內(nèi)部的同步通訊會(huì)占用大量的網(wǎng)絡(luò)帶寬。
二、部署方案
本方案中是在多臺(tái)機(jī)器之間部署rabbitmq的cluster,要求如下:這幾個(gè)節(jié)點(diǎn)需要再同一個(gè)局域網(wǎng)內(nèi);這幾個(gè)節(jié)點(diǎn)需要有相同的erlang cookie,否則不能正常通信,為了實(shí)現(xiàn)cookie內(nèi)容一致,采用scp的方式進(jìn)行。
1、環(huán)境介紹
rabbitmq01 192.168.101.11
rabbitmq02 192.168.101.12
rabbitmq03 192.168.101.13
操作系統(tǒng):centos6.7
2、部署過(guò)程
(1)分別在3臺(tái)機(jī)器上配置/etc/hosts,如下
node1 192.168.101.11
node2 192.168.101.12
node3 192.168.101.13
(2)分別在3臺(tái)機(jī)器上安裝erLang和rabbitmq
安裝erlang
安裝依賴(lài)包
yum install -y *epel* gcc-c++ unixODBC unixODBC-devel openssl-devel ncurses-devel
編譯安裝
tar -zxvf otp_src_19.0.tar.gzcd otp_src_19.0./configure --prefix=/usr/local/bin/erlang --without-javacmake && make installecho "export PATH=$PATH:/usr/local/bin/erlang/bin:/usr/local/bin/rabbitmq_server-3.6.5/sbin" >> /etc/profilesource /etc/profile
出現(xiàn)erl命令則說(shuō)明安裝成功;
安裝rabbitmq
編譯安裝
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-generic-unix-3.6.5.tar.xzyum install -y xzxz -d rabbitmq-server-3.6.3.tar.xztar -xvf rabbitmq-server-generic-unix-3.6.5.tar -C /usr/local/bin/echo "export PATH=$PATH:/usr/local/bin/erlang/bin:/usr/local/bin/rabbitmq_server-3.6.5/sbin" >> /etc/profilesource /etc/profile
導(dǎo)入rabbitmq的管理界面
rabbitmq-plugins enable rabbitmq_management
設(shè)置erlang
找到erlang cookie文件的位置,官方在介紹集群的文檔中提到過(guò).erlang.cookie一般會(huì)存在這兩個(gè)地址:第一個(gè)是$home/.erlang.cookie;第二個(gè)地方就是/var/lib/rabbitmq/.erlang.cookie。如果我們使用解壓縮方式安裝部署的rabbitmq,那么這個(gè)文件會(huì)在${home}目錄下,也就是$home/.erlang.cookie。如果我們使用rpm等安裝包方式進(jìn)行安裝的,那么這個(gè)文件會(huì)在/var/lib/rabbitmq目錄下。
這里將 node1 的該文件復(fù)制到 node2、node3,注意這個(gè)文件的權(quán)限是 400(默認(rèn)即是400),因此采用scp的方式只拷貝內(nèi)容即可;
可以通過(guò)cat $home/.erlang.cookie來(lái)查看三臺(tái)機(jī)器的cookie是否一致,設(shè)置erlang的目的是要保證集群內(nèi)的cookie內(nèi)容一致。
使用-detached參數(shù)運(yùn)行各節(jié)點(diǎn)
rabbitmqctl stoprabbitmq-server -detached
然后可以通過(guò)rabbitmqctl cluster_status查看節(jié)點(diǎn)狀態(tài)。PS:要先拷貝cookie到另外兩臺(tái)機(jī)器上,保證三臺(tái)機(jī)器上的cookie是一致的,然后再啟動(dòng)服務(wù)。
由于guest這個(gè)用戶(hù),只能在本地訪(fǎng)問(wèn),所以我們要新增一個(gè)用戶(hù)并賦予權(quán)限:
添加用戶(hù)并設(shè)置密碼:
rabbitmqctl add_user admin 123456
添加權(quán)限(使admin用戶(hù)對(duì)虛擬主機(jī)“/” 具有所有權(quán)限):
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
修改用戶(hù)角色(加入administrator用戶(hù)組)
rabbitmqctl set_user_tags admin administrator
然后就可以遠(yuǎn)程訪(fǎng)問(wèn)了,然后可直接配置用戶(hù)權(quán)限等信息。到此,就可以通過(guò)http://ip:15672 使用admin 123456 進(jìn)行登陸了。
到這里的話(huà),每個(gè)節(jié)點(diǎn)是作為單獨(dú)的一臺(tái)RabbitMQ存在的,也可以正常提供服務(wù)了
(3)組成集群
rabbitmq-server啟動(dòng)時(shí),會(huì)一起啟動(dòng)節(jié)點(diǎn)和應(yīng)用,它預(yù)先設(shè)置RabbitMQ應(yīng)用為standalone模式。要將一個(gè)節(jié)點(diǎn)加入到現(xiàn)有的集群中,你需要停止這個(gè)應(yīng)用,并將節(jié)點(diǎn)設(shè)置為原始狀態(tài)。如果使用./rabbitmqctl stop,應(yīng)用和節(jié)點(diǎn)都將被關(guān)閉。所以使用rabbitmqctl stop_app僅僅關(guān)閉應(yīng)用。
將 node2、node3與 node1 組成集群,這里以node2為例
node2# rabbitmqctl stop_app
node2# rabbitmqctl join_cluster rabbit@node1 ####這里集群的名字一定不要寫(xiě)錯(cuò)了
node2# rabbitmqctl start_app
將node3重復(fù)上述操作,也加入node1的集群。
則此時(shí) node2 與 node3 也會(huì)自動(dòng)建立連接,集群配置完畢;(PS:如果要使用內(nèi)存節(jié)點(diǎn),則可以使用node2 # rabbitmqctl join_cluster --ram rabbit@node1加入集群)集群配置好后,可以在 RabbitMQ 任意節(jié)點(diǎn)上執(zhí)行 rabbitmqctl cluster_status 來(lái)查看是否集群配置成功。
node3# rabbitmqctl cluster_status
Cluster status of node rabbit@node3 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
{running_nodes,[rabbit@node1,rabbit@node2,rabbit@node3]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]},
{alarms,[{rabbit@node1,[]},{rabbit@node2,[]},{rabbit@node3,[]}]}]
可知,集群的名稱(chēng)默認(rèn)為rabbit@node1;
PS:另外一種查看集群是否成功的方式,在web頁(yè)面上的“Queues”的列表中,查看有如下顯示為“同步鏡像到node2”,則也表示集群配置成功
(4)設(shè)置鏡像隊(duì)列策略
在任意一個(gè)節(jié)點(diǎn)上執(zhí)行如下操作(這里在node1上執(zhí)行)
首先,在web界面,登陸后,點(diǎn)擊“Admin--Virtual Hosts(頁(yè)面右側(cè))”,在打開(kāi)的頁(yè)面上的下方的“Add a new virtual host”處增加一個(gè)虛擬主機(jī),同時(shí)給用戶(hù)“admin”和“guest”均加上權(quán)限(在頁(yè)面直接設(shè)置、點(diǎn)點(diǎn)點(diǎn)即可);
然后,在linux中執(zhí)行如下命令
rabbitmqctl set_policy -p coresystem ha-all "^" '{"ha-mode":"all"}'
"coresystem" vhost名稱(chēng), "^"匹配所有的隊(duì)列, ha-all 策略名稱(chēng)為ha-all, '{"ha-mode":"all"}' 策略模式為 all 即復(fù)制到所有節(jié)點(diǎn),包含新增節(jié)點(diǎn)。
則此時(shí)鏡像隊(duì)列設(shè)置成功。(這里的虛擬主機(jī)coresystem是代碼中需要用到的虛擬主機(jī),虛擬主機(jī)的作用是做一個(gè)消息的隔離,本質(zhì)上可認(rèn)為是一個(gè)rabbitmq-server,是否增加虛擬主機(jī),增加幾個(gè),這是由開(kāi)發(fā)中的業(yè)務(wù)決定,即有哪幾類(lèi)服務(wù),哪些服務(wù)用哪一個(gè)虛擬主機(jī),這是一個(gè)規(guī)劃)。
--------------------------------------------#########################--------------------------------------------------------------------------------------------------
PS:這里補(bǔ)充一些對(duì)于設(shè)置鏡像隊(duì)列策略的說(shuō)明
------------------------------------------------########################-----------------------------------------------------------------------------------------------------
將所有隊(duì)列設(shè)置為鏡像隊(duì)列,即隊(duì)列會(huì)被復(fù)制到各個(gè)節(jié)點(diǎn),各個(gè)節(jié)點(diǎn)狀態(tài)保持一直。完成這 6 個(gè)步驟后,RabbitMQ 高可用集群就已經(jīng)搭建好了,最后一個(gè)步驟就是搭建均衡器。
(5)安裝并配置HA
PS:可以使用阿里云的內(nèi)網(wǎng)slb來(lái)實(shí)現(xiàn)負(fù)載均衡,不用自己搭建HA。這里僅演示如下:
在192.168.101.11上yum安裝HAProxy(yum -y install HAProxy),然后修改 /etc/haproxy/haproxy.cfg:
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/statsdefaults log global mode tcp option tcplog option dontlognull retries 3 option redispatch maxconn 2000 contimeout 5s clitimeout 120s srvtimeout 120s listen rabbitmq_cluster 192.168.101.11:5670 mode tcp balance roundrobin server rabbit1 192.168.101.11:5672 check inter 5000 rise 2 fall 2 server rabbit2 192.168.101.12:5672 check inter 5000 rise 2 fall 2 server rabbit3 192.168.101.13:5672 check inter 5000 rise 2 fall 2 listen private_monitoring :8100 mode http option httplog stats enable stats uri /rabbitmqstats stats refresh 5s
重啟HAProxy
service haproxy restart
登錄瀏覽器輸入地址http://192.168.101.11:8100/rabbitmqstats查看HAProxy的狀態(tài)
三、常見(jiàn)問(wèn)題
常見(jiàn)錯(cuò)誤:
1、使用 rabbitmq-server -detached命令啟動(dòng)rabbitmq時(shí),出現(xiàn)以下提示W(wǎng)arning: PID file not written; -detached was passed,此時(shí)使用rabbitmqctl status提示服務(wù)已啟動(dòng),可知此問(wèn)題不用解決。
2、由于更改hostname文件,在每次rabbitmqctl stop或者rabbitmqctl cluster_status等,只要是rabbitmq的命令就報(bào)錯(cuò),提示大概如下
Cluster status of node rabbit@web2 ...
Error: unable to connect to node rabbit@web2: nodedown
DIAGNOSTICS
===========
attempted to contact: [rabbit@web2]
rabbit@web2:
* connected to epmd (port 4369) on web2
* epmd reports node 'rabbit' running on port 25672
* TCP connection succeeded but Erlang distribution failed
* Hostname mismatch: node "rabbit@mq2" believes its host is different. Please ensure that hostnames resolve the same way locally and on "rabbit@mq2"
current node details:
- node name: 'rabbitmq-cli-11@web2'
- home dir: /root
- cookie hash: SGwxMdJ3PjEXG1asIEFpBg==
此時(shí)先ps aux | grep mq,然后kill -9 該進(jìn)程,然后再rabbitmq-server -detached即可解決。(即先強(qiáng)殺,再重新啟動(dòng))
3、使用rabbitmqctl stop,rabbitmq-server -detached重新啟動(dòng)后,原先添加的用戶(hù)admin、虛擬主機(jī)coresystem等均丟失,還需要重新添加。
采用腳本啟動(dòng),在腳本中寫(xiě)好啟動(dòng)好需要加載的各配置項(xiàng)(創(chuàng)建admin用戶(hù)并授權(quán),創(chuàng)建虛擬主機(jī)并授權(quán),配置鏡像隊(duì)列)。
3、命令
rabbitmqctl stop_app 僅關(guān)閉應(yīng)用,不關(guān)閉節(jié)點(diǎn)rabbitmqctl start_app 開(kāi)啟應(yīng)用rabbitmq--server -detached 啟動(dòng)節(jié)點(diǎn)和應(yīng)用rabbitmqctl 關(guān)閉節(jié)點(diǎn)和應(yīng)用
4、常用命令:
Rabbitmq服務(wù)器的主要通過(guò)rabbitmqctl和rabbimq-plugins兩個(gè)工具來(lái)管理,以下是一些常用功能。
1). 服務(wù)器啟動(dòng)與關(guān)閉
啟動(dòng): rabbitmq-server –detached 關(guān)閉:rabbitmqctl stop 若單機(jī)有多個(gè)實(shí)例,則在rabbitmqctlh后加–n 指定名稱(chēng)
2). 插件管理
開(kāi)啟某個(gè)插件:rabbitmq-plugins enable xxx 關(guān)閉某個(gè)插件:rabbitmq-plugins disable xxx 注意:重啟服務(wù)器后生效。
3).virtual_host管理
新建virtual_host: rabbitmqctl add_vhost xxx 撤銷(xiāo)virtual_host:rabbitmqctl delete_vhost xxx
4). 用戶(hù)管理
新建用戶(hù):rabbitmqctl add_user xxxpwd 刪除用戶(hù): rabbitmqctl delete_user xxx 查看用戶(hù):rabbitmqctl list_users 改密碼: rabbimqctlchange_password {username} {newpassword} 設(shè)置用戶(hù)角色:rabbitmqctlset_user_tags {username} {tag ...} Tag可以為 administrator,monitoring, management
5). 權(quán)限管理
權(quán)限設(shè)置:set_permissions [-pvhostpath] {user} {conf} {write} {read} Vhostpath Vhost路徑 user 用戶(hù)名 Conf 一個(gè)正則表達(dá)式match哪些配置資源能夠被該用戶(hù)訪(fǎng)問(wèn)。 Write 一個(gè)正則表達(dá)式match哪些配置資源能夠被該用戶(hù)讀。 Read 一個(gè)正則表達(dá)式match哪些配置資源能夠被該用戶(hù)訪(fǎng)問(wèn)。
6). 獲取服務(wù)器狀態(tài)信息
服務(wù)器狀態(tài):rabbitmqctl status ##其中可查看rabbitmq的版本信息
7).獲取集群狀態(tài)信息
rabbitmqctl cluster_status
本文出自http://blog.csdn.net/jxdl6655/article/details/78194191
聯(lián)系客服