rabbitmq叢集部署及設定

2020-08-12 14:48:08

訊息中介軟體rabbitmq,一般以叢集方式部署,主要提供訊息的接受和發送,實現各微服務之間的訊息非同步。本篇將以rabbitmq+HA方式進行部署。

一、原理介紹

rabbitmq是依據erlang的分佈式特性(RabbitMQ底層是通過Erlang架構來實現的,所以rabbitmqctl會啓動Erlang節點,並基於Erlang節點來使用Erlang系統連線RabbitMQ節點,在連線過程中需要正確的Erlang Cookie和節點名稱,Erlang節點通過交換Erlang Cookie以獲得認證)來實現的,所以部署rabbitmq分佈式叢集時要先安裝erlang,並把其中一個服務的cookie複製到另外的節點。

rabbitmq叢集中,各個rabbitmq爲對等節點,即每個節點均提供給用戶端連線,進行訊息的接收和發送。節點分爲記憶體節點和磁碟節點,一般的,均應建立爲磁碟節點,爲了防止機器重新啓動後的訊息消失;

RabbitMQ的Cluster叢集模式一般分爲兩種,普通模式和映象模式。訊息佇列通過rabbitmq HA映象佇列進行訊息佇列實體複製。

普通模式下,以兩個節點(rabbit01、rabbit02)爲例來進行說明。對於Queue來說,訊息實體只存在於其中一個節點rabbit01(或者rabbit02),rabbit01和rabbit02兩個節點僅有相同的元數據,即佇列的結構。當訊息進入rabbit01節點的Queue後,consumer從rabbit02節點消費時,RabbitMQ會臨時在rabbit01、rabbit02間進行訊息傳輸,把A中的訊息實體取出並經過B發送給consumer。所以consumer應儘量連線每一個節點,從中取訊息。即對於同一個邏輯佇列,要在多個節點建立物理Queue。否則無論consumer連rabbit01或rabbit02,出口總在rabbit01,會產生瓶頸。

映象模式下,將需要消費的佇列變爲映象佇列,存在於多個節點,這樣就可以實現RabbitMQ的HA高可用性。作用就是訊息實體會主動在映象節點之間實現同步,而不是像普通模式那樣,在consumer消費數據時臨時讀取。缺點就是,叢集內部的同步通訊會佔用大量的網路頻寬。

二、部署方案

本方案中是在多臺機器之間部署rabbitmq的cluster,要求如下:這幾個節點需要再同一個區域網內;這幾個節點需要有相同的erlang cookie,否則不能正常通訊,爲了實現cookie內容一致,採用scp的方式進行。

1、環境介紹

rabbitmq01 192.168.101.11   

rabbitmq02 192.168.101.12  

rabbitmq03 192.168.101.13

操作系統:centos6.7

2、部署過程

(1)分別在3臺機器上設定/etc/hosts,如下

 

node1 192.168.101.11   

node2 192.168.101.12  

node3 192.168.101.13

(2)分別在3臺機器上安裝erLang和rabbitmq

安裝erlang

安裝依賴包

 

yum install -y *epel* gcc-c++ unixODBC unixODBC-devel openssl-devel ncurses-devel

編譯安裝

 

 


 
  1. tar -zxvf otp_src_19.0.tar.gz

  2. cd otp_src_19.0

  3. ./configure --prefix=/usr/local/bin/erlang --without-javac

  4. make && make install

  5. echo "export PATH=$PATH:/usr/local/bin/erlang/bin:/usr/local/bin/rabbitmq_server-3.6.5/sbin" >> /etc/profile

  6. source /etc/profile

出現erl命令則說明安裝成功;

 

安裝rabbitmq

編譯安裝

 


 
  1. wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-generic-unix-3.6.5.tar.xz

  2. yum install -y xz

  3. xz -d rabbitmq-server-3.6.3.tar.xz

  4. tar -xvf rabbitmq-server-generic-unix-3.6.5.tar -C /usr/local/bin/

  5. echo "export PATH=$PATH:/usr/local/bin/erlang/bin:/usr/local/bin/rabbitmq_server-3.6.5/sbin" >> /etc/profile

  6. source /etc/profile

匯入rabbitmq的管理介面

 

rabbitmq-plugins enable rabbitmq_management

設定erlang

 

找到erlang cookie檔案的位置,官方在介紹叢集的文件中提到過.erlang.cookie一般會存在這兩個地址:第一個是$home/.erlang.cookie;第二個地方就是/var/lib/rabbitmq/.erlang.cookie。如果我們使用解壓縮方式安裝部署的rabbitmq,那麼這個檔案會在${home}目錄下,也就是$home/.erlang.cookie。如果我們使用rpm等安裝包方式進行安裝的,那麼這個檔案會在/var/lib/rabbitmq目錄下。

這裏將 node1 的該檔案複製到 node2、node3,注意這個檔案的許可權是 400(預設即是400),因此採用scp的方式只拷貝內容即可;

可以通過cat  $home/.erlang.cookie來檢視三臺機器的cookie是否一致,設定erlang的目的是要保證叢集內的cookie內容一致。

使用-detached參數執行各節點

 


 
  1. rabbitmqctl stop

  2. rabbitmq-server -detached

然後可以通過rabbitmqctl cluster_status檢視節點狀態。PS:要先拷貝cookie到另外兩臺機器上,保證三臺機器上的cookie是一致的,然後再啓動服務。

由於guest這個使用者,只能在本地存取,所以我們要新增一個使用者並賦予許可權:

新增使用者並設定密碼:

 

rabbitmqctl add_user  admin 123456

新增許可權(使admin使用者對虛擬主機「/」 具有所有許可權):

 

rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"

修改使用者角色(加入administrator使用者組)

 

rabbitmqctl set_user_tags admin administrator

 

然後就可以遠端訪問了,然後可直接設定使用者許可權等資訊。到此,就可以通過http://ip:15672 使用admin 123456 進行登陸了。

到這裏的話,每個節點是作爲單獨的一臺RabbitMQ存在的,也可以正常提供服務了

(3)組成叢集

rabbitmq-server啓動時,會一起啓動節點和應用,它預先設定RabbitMQ應用爲standalone模式。要將一個節點加入到現有的叢集中,你需要停止這個應用,並將節點設定爲原始狀態。如果使用./rabbitmqctl stop,應用和節點都將被關閉。所以使用rabbitmqctl stop_app僅僅關閉應用。

將 node2、node3與 node1 組成叢集,這裏以node2爲例

node2# rabbitmqctl stop_app      

node2# rabbitmqctl join_cluster rabbit@node1               ####這裏叢集的名字一定不要寫錯了

node2# rabbitmqctl start_app

將node3重複上述操作,也加入node1的叢集。

則此時 node2 與 node3 也會自動建立連線,叢集設定完畢;(PS:如果要使用記憶體節點,則可以使用node2 # rabbitmqctl join_cluster --ram rabbit@node1加入叢集)叢集設定好後,可以在 RabbitMQ 任意節點上執行 rabbitmqctl cluster_status 來檢視是否叢集設定成功。

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,[]}]}]
可知,叢集的名稱預設爲rabbit@node1;

PS:另外一種檢視叢集是否成功的方式,在web頁面上的「Queues」的列表中,檢視有如下顯示爲「同步映象到node2」,則也表示叢集設定成功

(4)設定映象佇列策略

在任意一個節點上執行如下操作(這裏在node1上執行)

首先,在web介面,登陸後,點選「Admin--Virtual Hosts(頁面右側)」,在開啓的頁面上的下方的「Add a new virtual host」處增加一個虛擬主機,同時給使用者「admin」和「guest」均加上許可權(在頁面直接設定、點點點即可);

然後,在linux中執行如下命令

 

rabbitmqctl set_policy -p coresystem  ha-all "^" '{"ha-mode":"all"}'

"coresystem" vhost名稱, "^"匹配所有的佇列, ha-all 策略名稱爲ha-all, '{"ha-mode":"all"}' 策略模式爲 all 即複製到所有節點,包含新增節點。

則此時映象佇列設定成功。(這裏的虛擬主機coresystem是程式碼中需要用到的虛擬主機,虛擬主機的作用是做一個訊息的隔離,本質上可認爲是一個rabbitmq-server,是否增加虛擬主機,增加幾個,這是由開發中的業務決定,即有哪幾類服務,哪些服務用哪一個虛擬主機,這是一個規劃)。

--------------------------------------------#########################--------------------------------------------------------------------------------------------------

PS:這裏補充一些對於設定映象佇列策略的說明

 


 
  1. rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

  2.  
  3. -p Vhost: 可選參數,針對指定vhost下的queue進行設定

  4. Name: policy的名稱

  5. Pattern: queue的匹配模式(正則表達式)

  6. Definition:映象定義,包括三個部分ha-mode, ha-params, ha-sync-mode

  7. ha-mode:指明映象佇列的模式,有效值爲 all/exactly/nodes

  8. all:表示在叢集中所有的節點上進行映象

  9. exactly:表示在指定個數的節點上進行映象,節點的個數由ha-params指定

  10. nodes:表示在指定的節點上進行映象,節點名稱通過ha-params指定

  11. ha-params:ha-mode模式需要用到的參數

  12. ha-sync-mode:進行佇列中訊息的同步方式,有效值爲automatic和manual

  13. priority:可選參數,policy的優先順序

------------------------------------------------########################-----------------------------------------------------------------------------------------------------

 

 

將所有佇列設定爲映象佇列,即佇列會被複制到各個節點,各個節點狀態保持一直。完成這 6 個步驟後,RabbitMQ 高可用叢集就已經搭建好了,最後一個步驟就是搭建均衡器。

(5)安裝並設定HA

PS:可以使用阿裡雲的內網slb來實現負載均衡,不用自己搭建HA。這裏僅演示如下:

在192.168.101.11上yum安裝HAProxy(yum -y install HAProxy),然後修改 /etc/haproxy/haproxy.cfg:

 


 
  1. global

  2.  
  3. log 127.0.0.1 local2

  4.  
  5. chroot /var/lib/haproxy

  6. pidfile /var/run/haproxy.pid

  7. maxconn 4000

  8. user haproxy

  9. group haproxy

  10. daemon

  11.  
  12. stats socket /var/lib/haproxy/stats

  13.  
  14. defaults

  15. log global

  16. mode tcp

  17. option tcplog

  18. option dontlognull

  19. retries 3

  20. option redispatch

  21. maxconn 2000

  22. contimeout 5s

  23. clitimeout 120s

  24. srvtimeout 120s

  25.  
  26. listen rabbitmq_cluster 192.168.101.11:5670

  27. mode tcp

  28. balance roundrobin

  29. server rabbit1 192.168.101.11:5672 check inter 5000 rise 2 fall 2

  30. 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的狀態

 

三、常見問題

 

常見錯誤:

1、使用 rabbitmq-server -detached命令啓動rabbitmq時,出現以下提示Warning: PID file not written; -detached was passed,此時使用rabbitmqctl status提示服務已啓動,可知此問題不用解決。

2、由於更改hostname檔案,在每次rabbitmqctl stop或者rabbitmqctl cluster_status等,只要是rabbitmq的命令就報錯,提示大概如下

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==

此時先ps aux | grep mq,然後kill -9 該進程,然後再rabbitmq-server -detached即可解決。(即先強殺,再重新啓動)

3、使用rabbitmqctl stop,rabbitmq-server -detached重新啓動後,原先新增的使用者admin、虛擬主機coresystem等均丟失,還需要重新新增。

採用指令碼啓動,在指令碼中寫好啓動好需要載入的各設定項(建立admin使用者並授權,建立虛擬主機並授權,設定映象佇列)。

3、命令


 
  1. rabbitmqctl stop_app 僅關閉應用,不關閉節點

  2. rabbitmqctl start_app 開啓應用

  3. rabbitmq--server -detached 啓動節點和應用

  4. rabbitmqctl 關閉節點和應用

4、常用命令:

Rabbitmq伺服器的主要通過rabbitmqctl和rabbimq-plugins兩個工具來管理,以下是一些常用功能。

1). 伺服器啓動與關閉


 
  1. 啓動: rabbitmq-server –detached

  2. 關閉:rabbitmqctl stop

  3. 若單機有多個範例,則在rabbitmqctlh後加–n 指定名稱

  4.  

2). 外掛管理


 
  1. 開啓某個外掛:rabbitmq-plugins enable xxx

  2. 關閉某個外掛:rabbitmq-plugins disable xxx

  3. 注意:重新啓動伺服器後生效。

3).virtual_host管理


 
  1. 新建virtual_host: rabbitmqctl add_vhost xxx

  2. 復原virtual_host:rabbitmqctl delete_vhost xxx

  3.  

4). 使用者管理


 
  1. 新建使用者:rabbitmqctl add_user xxxpwd

  2. 刪除使用者: rabbitmqctl delete_user xxx

  3. 檢視使用者:rabbitmqctl list_users

  4.  改密碼: rabbimqctlchange_password {username} {newpassword}

  5. 設定使用者角色:rabbitmqctlset_user_tags {username} {tag ...}

  6. Tag可以爲 administrator,monitoring, management

  7.  

5). 許可權管理


 
  1. 許可權設定:set_permissions [-pvhostpath] {user} {conf} {write} {read}

  2. Vhostpath

  3. Vhost路徑

  4. user

  5. 使用者名稱

  6. Conf

  7. 一個正則表達式match哪些設定資源能夠被該使用者存取。

  8. Write

  9. 一個正則表達式match哪些設定資源能夠被該使用者讀。

  10. Read

  11. 一個正則表達式match哪些設定資源能夠被該使用者存取。

  12.  

6). 獲取伺服器狀態資訊

  伺服器狀態:rabbitmqctl status     ##其中可檢視rabbitmq的版本資訊

7).獲取叢集狀態資訊

rabbitmqctl cluster_status