閱讀目錄:css
由於公司測試服務器暫不能用,只能在本身電腦上從新搭建一下 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
首先,在node1
服務器上,修改vi /etc/hostname
:web
node1
在node2
服務器上,修改vi /etc/hostname
:segmentfault
node2
而後在node1
服務器上,修改vi /etc/hosts
:centos
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
下面以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
服務器上,再作重複一邊。
問題說明:RabbitMQ 要求在集羣中至少有一個磁盤節點,全部其餘節點能夠是內存節點,當節點加入或者離開集羣時,必需要將該變動通知到至少一個磁盤節點。若是集羣中惟一的一個磁盤節點崩潰的話,集羣仍然能夠保持運行,可是沒法進行其餘操做(增刪改查),直到節點恢復。
解決方案:設置兩個磁盤節點,至少有一個是可用的,能夠保存元數據的更改。
Erlang Cookie 是保證不一樣節點能夠相互通訊的密鑰,要保證集羣中的不一樣節點相互通訊必須共享相同的 Erlang Cookie。具體的目錄存放在/var/lib/rabbitmq/.erlang.cookie
。
說明:這就要從 rabbitmqctl 命令的工做原理提及,RabbitMQ 底層是經過 Erlang 架構來實現的,因此 rabbitmqctl 會啓動 Erlang 節點,並基於 Erlang 節點來使用 Erlang 系統鏈接 RabbitMQ 節點,在鏈接過程當中須要正確的 Erlang Cookie 和節點名稱,Erlang 節點經過交換 Erlang Cookie 以得到認證。
RabbitMQ 的 Cluster 集羣模式通常分爲兩種,普通模式和鏡像模式。
鏡像隊列實現了 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 分佈式集羣架構
理解了上面的概念以後,咱們再搭建 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(node1
和node2
分別執行):
[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
查看集羣的狀態(包含node1
和node2
節點):
[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 管理界面,看到集羣的信息:
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 負載均衡信息:
參考資料: