搭建 RabbitMQ Server 高可用集羣

閱讀目錄:css

  • 準備工做
  • 搭建 RabbitMQ Server 單機版
  • RabbitMQ Server 高可用集羣相關概念
  • 搭建 RabbitMQ Server 高可用集羣
  • 搭建 HAProxy 負載均衡

由於公司測試服務器暫不能用,只能在本身電腦上從新搭建一下 RabbitMQ Server 高可用集羣,正好把這個過程記錄下來,以便往後查看。html

公司測試服務器上的 RabbitMQ 集羣,我搭建的是三臺服務器,由於本身電腦空間有限,這邊只能搭建兩臺服務器用做高可用集羣,用的是 Vagrant 虛擬機管理工具。node

環境介紹:python

RabbitMQ 節點 IP 地址 工做模式
node1 192.168.1.50 DISK CentOS 7.0 - 64位
node2 192.168.1.51 DISK CentOS 7.0 - 64位

總體架構:git

1. 準備工做

首先,在node1服務器上,修改vi /etc/hostnameweb

node1

node2服務器上,修改vi /etc/hostnamesegmentfault

node2

而後在node1服務器上,修改vi /etc/hostscentos

node1 192.168.1.50 node2 192.168.1.51 127.0.0.1 node1 ::1 node1

node2服務器上,修改vi /etc/hosts瀏覽器

192.168.1.50 node1 192.168.1.51 node2 127.0.0.1 node2 ::1 node2

而後查看下hostnamectl status,若是不正確的話,須要再進行設置下:bash

[root@node1 ~]# hostnamectl status Static hostname: node1 Icon name: computer-vm Chassis: vm Machine ID: 241163503ce842c489360d0a48a606fc Boot ID: cdb59c025cb447e3afed7317af78979e Virtualization: oracle Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-229.el7.x86_64 Architecture: x86_64 [root@node1 ~]# hostnamectl --static set-hostname node1

爲了後面咱們安裝的順利,咱們最好再配置一下代理:

[root@node1 ~]# export http_proxy=http://192.168.1.44:1087;export https_proxy=http://192.168.1.44:1087; [root@node1 ~]# curl ip.cn 當前 IP:104.245.13.31 來自:美國 Linost

2. 搭建 RabbitMQ Server 單機版

下面以node1服務器作演示示例。

首先,更新軟件包和存儲庫:

[root@node1 ~]# yum -y update

而後安裝 Erlang(RabbitMQ 運行須要 Erlang 環境):

[root@node1 ~]# vi /etc/yum.repos.d/rabbitmq-erlang.repo [root@node1 ~]# [rabbitmq-erlang] name=rabbitmq-erlang baseurl=https://dl.bintray.com/rabbitmq/rpm/erlang/20/el/7 gpgcheck=1 gpgkey=https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc repo_gpgcheck=0 enabled=1 [root@node1 ~]# yum -y install erlang socat

而後安裝 RabbitMQ Server:

[root@node1 ~]# mkdir -p ~/download && cd ~/download [root@node1 download]# wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10-1.el7.noarch.rpm [root@node1 download]# rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc [root@node1 download]# rpm -Uvh rabbitmq-server-3.6.10-1.el7.noarch.rpm

卸載 RabbitMQ 命令:

[root@node1 ~]# rpm -e rabbitmq-server-3.6.10-1.el7.noarch [root@node1 ~]# rm -rf /var/lib/rabbitmq/ //清除rabbitmq配置文件

安裝好以後,就能夠啓動 RabbitMQ Server 了:

[root@node1 download]# systemctl start rabbitmq-server

也能夠添加到系統服務中啓動:

[root@node1 download]# systemctl enable rabbitmq-server Created symlink from /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service to /usr/lib/systemd/system/rabbitmq-server.service.

啓動成功以後,咱們能夠查看下 RabbitMQ Server 的狀態:

[root@node1 download]# systemctl status rabbitmq-server ● rabbitmq-server.service - RabbitMQ broker Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled) Active: active (running) since 五 2018-04-27 04:44:31 CEST; 3min 27s ago Process: 17216 ExecStop=/usr/sbin/rabbitmqctl stop (code=exited, status=0/SUCCESS) Main PID: 17368 (beam.smp) Status: "Initialized" CGroup: /system.slice/rabbitmq-server.service ├─17368 /usr/lib64/erlang/erts-9.3/bin/beam.smp -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 32000 -K true -- -root /usr/lib64/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr... ├─17521 /usr/lib64/erlang/erts-9.3/bin/epmd -daemon ├─17655 erl_child_setup 1024 ├─17675 inet_gethost 4 └─17676 inet_gethost 4 4月 27 04:44:30 node1 rabbitmq-server[17368]: RabbitMQ 3.6.10. Copyright (C) 2007-2017 Pivotal Software, Inc. 4月 27 04:44:30 node1 rabbitmq-server[17368]: ## ## Licensed under the MPL. See http://www.rabbitmq.com/ 4月 27 04:44:30 node1 rabbitmq-server[17368]: ## ## 4月 27 04:44:30 node1 rabbitmq-server[17368]: ########## Logs: /var/log/rabbitmq/rabbit@node1.log 4月 27 04:44:30 node1 rabbitmq-server[17368]: ###### ## /var/log/rabbitmq/rabbit@node1-sasl.log 4月 27 04:44:30 node1 rabbitmq-server[17368]: ########## 4月 27 04:44:30 node1 rabbitmq-server[17368]: Starting broker... 4月 27 04:44:31 node1 rabbitmq-server[17368]: systemd unit for activation check: "rabbitmq-server.service" 4月 27 04:44:31 node1 systemd[1]: Started RabbitMQ broker. 4月 27 04:44:31 node1 rabbitmq-server[17368]: completed with 0 plugins. [root@node1 download]# systemctl enable rabbitmq-server ln -s '/usr/lib/systemd/system/rabbitmq-server.service' '/etc/systemd/system/multi-user.target.wants/rabbitmq-server.service'

而後啓動 RabbitMQ Web 管理控制檯:

[root@node1 download]# rabbitmq-plugins enable rabbitmq_management The following plugins have been enabled: amqp_client cowlib cowboy rabbitmq_web_dispatch rabbitmq_management_agent rabbitmq_management Applying plugin configuration to rabbit@node1... started 6 plugins.

RabbitMQ Server 默認guest用戶,只能localhost地址訪問,咱們還須要建立管理用戶:

[root@node1 download]# rabbitmqctl add_user admin admin123 && rabbitmqctl set_user_tags admin administrator && rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

而後添加防火牆運行訪問的端口:

[root@node1 download]# firewall-cmd --zone=public --permanent --add-port=4369/tcp && firewall-cmd --zone=public --permanent --add-port=25672/tcp && firewall-cmd --zone=public --permanent --add-port=5671-5672/tcp && firewall-cmd --zone=public --permanent --add-port=15672/tcp && firewall-cmd --zone=public --permanent --add-port=61613-61614/tcp && firewall-cmd --zone=public --permanent --add-port=1883/tcp && firewall-cmd --zone=public --permanent --add-port=8883/tcp success

從新啓動防火牆:

[root@node1 download]# firewall-cmd --reload success

上面這些作完了,RabbitMQ 單機版的部署也完成了,咱們能夠瀏覽器訪問``:

將上面的搭建過程,在node2服務器上,再作重複一邊。

3. RabbitMQ Server 高可用集羣相關概念

設計集羣的目的

  • 容許消費者和生產者在 RabbitMQ 節點崩潰的狀況下繼續運行。
  • 經過增長更多的節點來擴展消息通訊的吞吐量。

集羣配置方式

  • cluster:不支持跨網段,用於同一個網段內的局域網;能夠隨意的動態增長或者減小;節點之間須要運行相同版本的 RabbitMQ 和 Erlang。
  • federation:應用於廣域網,容許單臺服務器上的交換機或隊列接收發布到另外一臺服務器上交換機或隊列的消息,能夠是單獨機器或集羣。federation 隊列相似於單向點對點鏈接,消息會在聯盟隊列之間轉發任意次,直到被消費者接受。一般使用 federation 來鏈接 internet 上的中間服務器,用做訂閱分發消息或工做隊列。
  • shovel:鏈接方式與 federation 的鏈接方式相似,但它工做在更低層次。能夠應用於廣域網。

節點類型

  • RAM node:內存節點將全部的隊列、交換機、綁定、用戶、權限和 vhost 的元數據定義存儲在內存中,好處是可使得像交換機和隊列聲明等操做更加的快速。
  • Disk node:將元數據存儲在磁盤中,單節點系統只容許磁盤類型的節點,防止重啓 RabbitMQ 的時候,丟失系統的配置信息。

問題說明:RabbitMQ 要求在集羣中至少有一個磁盤節點,全部其餘節點能夠是內存節點,當節點加入或者離開集羣時,必需要將該變動通知到至少一個磁盤節點。若是集羣中惟一的一個磁盤節點崩潰的話,集羣仍然能夠保持運行,可是沒法進行其餘操做(增刪改查),直到節點恢復。
解決方案:設置兩個磁盤節點,至少有一個是可用的,能夠保存元數據的更改。

Erlang Cookie

Erlang Cookie 是保證不一樣節點能夠相互通訊的密鑰,要保證集羣中的不一樣節點相互通訊必須共享相同的 Erlang Cookie。具體的目錄存放在/var/lib/rabbitmq/.erlang.cookie

說明:這就要從 rabbitmqctl 命令的工做原理提及,RabbitMQ 底層是經過 Erlang 架構來實現的,因此 rabbitmqctl 會啓動 Erlang 節點,並基於 Erlang 節點來使用 Erlang 系統鏈接 RabbitMQ 節點,在鏈接過程當中須要正確的 Erlang Cookie 和節點名稱,Erlang 節點經過交換 Erlang Cookie 以得到認證。

鏡像隊列

RabbitMQ 的 Cluster 集羣模式通常分爲兩種,普通模式和鏡像模式。

  • 普通模式:默認的集羣模式,以兩個節點(rabbit0一、rabbit02)爲例來進行說明。對於 Queue 來講,消息實體只存在於其中一個節點 rabbit01(或者 rabbit02),rabbit01 和 rabbit02 兩個節點僅有相同的元數據,即隊列的結構。當消息進入 rabbit01 節點的 Queue 後,consumer 從 rabbit02 節點消費時,RabbitMQ 會臨時在 rabbit0一、rabbit02 間進行消息傳輸,把 A 中的消息實體取出並通過 B 發送給 consumer。因此 consumer 應儘可能鏈接每個節點,從中取消息。即對於同一個邏輯隊列,要在多個節點創建物理 Queue。不然不管 consumer 連 rabbit01 或 rabbit02,出口總在 rabbit01,會產生瓶頸。當 rabbit01 節點故障後,rabbit02 節點沒法取到 rabbit01 節點中還未消費的消息實體。若是作了消息持久化,那麼得等 rabbit01 節點恢復,而後纔可被消費;若是沒有持久化的話,就會產生消息丟失的現象。
  • 鏡像模式:將須要消費的隊列變爲鏡像隊列,存在於多個節點,這樣就能夠實現 RabbitMQ 的 HA 高可用性。做用就是消息實體會主動在鏡像節點之間實現同步,而不是像普通模式那樣,在 consumer 消費數據時臨時讀取。缺點就是,集羣內部的同步通信會佔用大量的網絡帶寬。

鏡像隊列實現了 RabbitMQ 的高可用性(HA),具體的實現策略以下所示:

ha-mode ha-params 功能
all 鏡像隊列將會在整個集羣中複製。當一個新的節點加入後,也會在這 個節點上覆制一份。
exactly count 鏡像隊列將會在集羣上覆制 count 份。若是集羣數量少於 count 時候,隊列會複製到全部節點上。若是大於 Count 集羣,有一個節點 crash 後,新進入節點也不會作新的鏡像。
nodes node name 鏡像隊列會在 node name 中複製。若是這個名稱不是集羣中的一個,這不會觸發錯誤。若是在這個 node list 中沒有一個節點在線,那麼這個 queue 會被聲明在 client 鏈接的節點。

實例列舉:

queue_args("x-ha-policy":"all") //定義字典來設置額外的隊列聲明參數 channel.queue_declare(queue="hello-queue",argument=queue_args)

若是須要設定特定的節點(以rabbit@localhost爲例),再添加一個參數:

queue_args("x-ha-policy":"nodes", "x-ha-policy-params":["rabbit@localhost"]) channel.queue_declare(queue="hello-queue",argument=queue_args)

能夠經過命令行查看那個主節點進行了同步:

$ rabbitmqctl list_queue name slave_pids synchronised_slave_pids

以上內容主要參考:RabbitMQ 分佈式集羣架構

4. 搭建 RabbitMQ Server 高可用集羣

理解了上面的概念以後,咱們再搭建 RabbitMQ Server 高可用集羣,就很是容易了。

默認.erlang.cookie文件是隱藏的,ls命令並不能查看,你也能夠手動搜索下文件:

[root@node1 ~]# find / -name ".erlang.cookie" /var/lib/rabbitmq/.erlang.cookie [root@node1 ~]# cat /var/lib/rabbitmq/.erlang.cookie LBOTELUJAMXDMIXNTZMB

node1服務器中的.erlang.cookie文件,拷貝到node2服務器上:

[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq

先中止運行節點,而後之後臺方式啓動 RabbitMQ Server(node1node2分別執行):

[root@node1 ~]# rabbitmqctl stop [root@node1 ~]# rabbitmq-server -detached

而後咱們以node1做爲集羣中心,在node2上執行加入集羣中心命令(節點類型爲磁盤節點):

[root@node1 ~]# rabbitmqctl stop_app [root@node1 ~]# rabbitmqctl reset [root@node1 ~]# rabbitmqctl join_cluster rabbit@node1 //默認是磁盤節點,若是是內存節點的話,須要加--ram參數 [root@node1 ~]# rabbitmqctl start_app

查看集羣的狀態(包含node1node2節點):

[root@node1 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node1 [{nodes,[{disc,[rabbit@node1,rabbit@node2]}]}, {running_nodes,[rabbit@node2,rabbit@node1]}, {cluster_name,<<"rabbit@node1">>}, {partitions,[]}, {alarms,[{rabbit@node2,[]},{rabbit@node1,[]}]}]

咱們能夠從 RabbitMQ Web 管理界面,看到集羣的信息:

5. 搭建 HAProxy 負載均衡

HAProxy 是一個免費的負載均衡軟件,能夠運行於大部分主流的 Linux 操做系統上。

HAProxy 提供了 L4(TCP) 和 L7(HTTP) 兩種負載均衡能力,具有豐富的功能。HAProxy 的社區很是活躍,版本更新快速(最新穩定版 1.7.2 於 2017/01/13 推出)。最關鍵的是,HAProxy 具有媲美商用負載均衡器的性能和穩定性。它當前不只僅是免費負載均衡軟件的首選,更幾乎成爲了惟一選擇。

由於 RabbitMQ 自己不提供負載均衡,下面咱們就搭建 HAProxy,用做 RabbitMQ 集羣的負載均衡。

HAProxy 安裝在node1服務器上,安裝命令:

[root@node1 ~]# rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm// [root@node1 ~]# yum -y install haproxy

配置 HAProxy:

[root@node1 ~]# cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak [root@node1 ~]# vi /etc/haproxy/haproxy.cfg

將下面的配置添加到/etc/haproxy/haproxy.cfg文件中:

global
    log 127.0.0.1 local0 info log 127.0.0.1 local1 notice daemon maxconn 4096 defaults log global mode tcp option tcplog option dontlognull retries 3 option abortonclose maxconn 4096 timeout connect 5000ms timeout client 3000ms timeout server 3000ms balance roundrobin listen private_monitoring bind 0.0.0.0:8100 mode http option httplog stats refresh 5s stats uri /stats stats realm Haproxy stats auth admin:admin listen rabbitmq_admin bind 0.0.0.0:8102 server node1 node1:15672 server node2 node2:15672 listen rabbitmq_cluster bind 0.0.0.0:8101 mode tcp option tcplog balance roundrobin timeout client 3h timeout server 3h server node1 node1:5672 check inter 5000 rise 2 fall 3 server node2 node2:5672 check inter 5000 rise 2 fall 3

而後啓動 HAProxy:

[root@node1 ~]# haproxy -f /etc/haproxy/haproxy.cfg

外部訪問的話,須要關閉下防火牆:

[root@node1 ~]# systemctl disable firewalld.service rm '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service' rm '/etc/systemd/system/basic.target.wants/firewalld.service' [root@node1 ~]# systemctl stop firewalld.service

HAProxy 配置了三個地址:

  • http://node1:8100/stats:HAProxy 負載均衡信息地址,帳號密碼:admin/admin
  • http://node1:8101:RabbitMQ Server Web 管理界面(基於負載均衡)。
  • http://node1:8102:RabbitMQ Server 服務地址(基於負載均衡)。

經過訪問http://node1:8100/stats,查看 HAProxy 負載均衡信息:

參考資料:

相關文章
相關標籤/搜索