后端75、103、69分別是3台rabbitmq節點做鏡像集群,前端103用haproxy作為負載均衡器
參照
https://www.cnblogs.com/sky-cheng/p/10709104.html
vim /etc/hosts
172.28.18.75 node1
172.28.18.103 node2
172.28.18.69 node3
RabbitMQ節點之間和命令行工具 (e.g. rabbitmqctl)是使用Cookie互通的,Cookie是一組隨機的數字+字母的字符串。當RabbitMQ服務器啟動的時候,Erlang VM會自動創建一個隨機內容的Cookie文件。如果是通過源安裝RabbitMQ的話,Erlang Cookie 文件在/var/lib/rabbitmq/.erlang.cookie。如果是通過源碼安裝的RabbitMQ,Erlang Cookie文件$HOME/.erlang.cookie。
首先需要將3個節點的cookie進行統一,將75的.erlang.cookie覆蓋到103和69的cookie
.erlang.cookie文件權限默認是400
[root@zabbix_server src]# ll -a /var/lib/rabbitmq/ 總用量 16 drwxr-xr-x 3 rabbitmq rabbitmq 4096 3月 29 05:48 . drwxr-xr-x. 34 root root 4096 4月 15 10:13 .. -r-------- 1 rabbitmq rabbitmq 20 4月 15 00:00 .erlang.cookie drwxr-x--- 4 rabbitmq rabbitmq 4096 4月 18 09:12 mnesia
修改權限為777
chmod 777 /var/lib/rabbitmq/.erlang.cookie
[root@zabbix_server src]# ll -a /var/lib/rabbitmq/.erlang.cookie -rwxrwxrwx 1 rabbitmq rabbitmq 20 4月 15 00:00 /var/lib/rabbitmq/.erlang.cookie
復制文件
[root@zabbix_server src]# scp -P25601 /var/lib/rabbitmq/.erlang.cookie root@172.28.18.103:/var/lib/rabbitmq/ root@172.28.18.103's password: .erlang.cookie 100% 20 0.0KB/s 00:00
[root@zabbix_server src]# scp -P25601 /var/lib/rabbitmq/.erlang.cookie root@172.28.18.69:/var/lib/rabbitmq/ root@172.28.18.69's password: .erlang.cookie 100% 20 0.0KB/s 00:00
驗證三個節點文件內容是否相同
[root@zabbix_server src]# cat /var/lib/rabbitmq/.erlang.cookie ATHUHJDWKYXPPLSHYCED
[root@localhost src]# cat /var/lib/rabbitmq/.erlang.cookie ATHUHJDWKYXPPLSHYCED
[root@localhost ~]# cat /var/lib/rabbitmq/.erlang.cookie ATHUHJDWKYXPPLSHYCED
再將node1、node2、node3將權限恢復為400
[root@zabbix_server src]# chmod 400 /var/lib/rabbitmq/.erlang.cookie
[root@localhost src]# chmod 400 /var/lib/rabbitmq/.erlang.cookie
[root@localhost ~]# chmod 400 /var/lib/rabbitmq/.erlang.cookie
先停止3個rabbitmq節點
[root@zabbix_server /]# rabbitmqctl stop
Stopping and halting node rabbit@zabbix_server ...
[root@zabbix_server /]#
注意修改3個服務器的主機名
[root@localhost src]# hostname
localhost.localdomain
[root@localhost src]# hostname node2.jinglong
[root@localhost src]# hostname node2.jinglong
重啟ssh登錄
[root@node2 ~]# hostname
node2.jinglong
顯示@ node2了
啟動3個節點 ,帶detached參數
[root@zabbix_server /]# rabbitmq-server -detached Warning: PID file not written; -detached was passed.
[root@zabbix_server src]# rabbitmqctl cluster_status Cluster status of node rabbit@zabbix_server ... [{nodes,[{disc,[rabbit@zabbix_server]}]}, {running_nodes,[rabbit@zabbix_server]}, {cluster_name,<<"rabbit@zabbix_server">>}, {partitions,[]}, {alarms,[{rabbit@zabbix_server,[]}]}]
[root@node2 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node2 ... [{nodes,[{disc,[rabbit@node2]}]}, {running_nodes,[rabbit@node2]}, {cluster_name,<<"rabbit@node2">>}, {partitions,[]}, {alarms,[{rabbit@node2,[]}]}]
[root@node3 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node3 ... [{nodes,[{disc,[rabbit@node3]}]}, {running_nodes,[rabbit@node3]}, {cluster_name,<<"rabbit@node3">>}, {partitions,[]}, {alarms,[{rabbit@node3,[]}]}]
3個節點啟動后,節點和應用同時啟動,應用默認是standalone模式,即單機模式,所以需要先停掉需要加入集群的node2、node3節點的應用,然后將節點進行加入集群設置:
在node2服務器上操作
[root@node2 ~]# rabbitmqctl stop_app
Stopping node rabbit@node2 ...
注意,這里不能使用 rabbitmqctl stop,這樣會將節點也停掉,就不能進行后續節點加入集群操作了,只能使用stop_app參數停掉應用。
將node2加入集群
[root@node2 ~]# rabbitmqctl join_cluster rabbit@zabbix_server Clustering node rabbit@node2 with rabbit@zabbix_server ... Error: unable to connect to nodes [rabbit@zabbix_server]: nodedown DIAGNOSTICS =========== attempted to contact: [rabbit@zabbix_server] rabbit@zabbix_server: * unable to connect to epmd (port 4369) on zabbix_server: nxdomain (non-existing domain) current node details: - node name: 'rabbitmq-cli-76@node2' - home dir: /var/lib/rabbitmq - cookie hash: W3bZoV8WKKWsCgfh3FFkzw==
報錯,(non-existing domain),此時排查3台服務器的/etc/hosts文件內容,保證和hostname名稱一致
vim /etc/hosts
172.28.18.75 zabbix_server
172.28.18.103 node2
172.28.18.69 node3
再次加入集群
[root@node2 ~]# rabbitmqctl join_cluster rabbit@zabbix_server
Clustering node rabbit@node2 with rabbit@zabbix_server ...
[root@node2 ~]#
查看集群狀態
[root@node2 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node2 ...
[{nodes,[{disc,[rabbit@node2,rabbit@zabbix_server]}]},
{alarms,[{rabbit@zabbix_server,[]}]}]
此時可以看到nodes里已經有2個節點了node2和zabbix_server,說明集群加入成功
在75上查看集群狀態
[root@zabbix_server src]# rabbitmqctl cluster_status Cluster status of node rabbit@zabbix_server ... [{nodes,[{disc,[rabbit@node2,rabbit@zabbix_server]}]}, {running_nodes,[rabbit@zabbix_server]}, {cluster_name,<<"rabbit@zabbix_server">>}, {partitions,[]}, {alarms,[{rabbit@zabbix_server,[]}]}]
也能看到有2個節點了,我們再把node3節點也加入集群
[root@node3 ~]# rabbitmqctl join_cluster rabbit@zabbix_server Clustering node rabbit@node3 with rabbit@zabbix_server ... [root@node3 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node3 ... [{nodes,[{disc,[rabbit@node2,rabbit@node3,rabbit@zabbix_server]}]}, {alarms,[{rabbit@zabbix_server,[]}]}]
此時,可以看到nodes里出現了node3節點,加入集群成功。我們再把node2和node3節點的應用啟動
我們打開75的管控台
此時節點信息里,已經出現了node2和node3,但是目前的狀態的未運行,所以我們需要把node2和node3的應用啟動
[root@node2 ~]# rabbitmqctl start_app
Starting node rabbit@node2 ...
[root@node3 ~]# rabbitmqctl start_app
Starting node rabbit@node3 ...
此時刷新75的管控台
集群中的3個節點都已經正常了
修改下集群名稱便於記憶
rabbitmqctl set_cluster_name rabbitmq_cluster
在任意一個節點執行設置鏡像隊列策略
[root@zabbix_server src]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' Setting policy "ha-all" for pattern "^" to "{\"ha-mode\":\"all\"}" with priority "0" ... [root@zabbix_server src]#
在任意一個節點管控台新建一個隊列,新建完畢后,立刻在其余2個節點都可以看到這個隊列
利用java 編寫一個生產者測試客戶端向其中一個節點隊列發送消息,其余2個節點都可以在管控台看到消息的同步
package com.hl95.rabbitmq.demo; import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class Producer { public static void main(String[]args) throws IOException,TimeoutException{ ConnectionFactory factory=new ConnectionFactory(); //配置連接屬性 factory.setHost("172.28.18.69"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("admin"); factory.setPassword("xxxxxx"); //得到連接 Connection connection=factory.newConnection(); //創建通道 Channel channel=connection.createChannel(); //聲明(創建)隊列 String queueName="test001"; channel.queueDeclare(queueName, true, false, false, null); //發送消息 String message="你好, RabbitMQ"; for(int i=0;i<200;i++){ channel.basicPublish("",queueName, null, message.getBytes("UTF-8")); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } channel.close(); connection.close(); } }
cd /usr/local/src wget https://github.com/haproxy/haproxy/archive/v1.5-dev20.tar.gz
tar -zxvf v1.5-dev20.tar.gz cd haproxy-1.5-dev20/ make TARGET=linux26 prefix=/usr/local/haproxy make install prefix=/usr/local/haproxy
mkdir /etc/haproxy touch /etc/haproxy/haproxy.conf
vim /etc/haproxy/haproxy.conf
global 2 log 127.0.0.1 local2 3 chroot /usr/local/haproxy 4 pidfile /var/run/haproxy.pid ###haproxy的pid存放路徑,啟動進程的用戶必須有權限訪問此文件 5 maxconn 65535 ###最大連接數,默認4000 6 daemon 7 8 defaults 9 mode tcp 10 option tcplog 11 log global 12 timeout connect 20s 13 timeout server 60s 14 timeout client 60s 15 retries 3 16 17 listen stats 18 bind 0.0.0.0:8888 #監聽端口 19 mode http 20 option httplog 21 stats refresh 5s #統計頁面自動刷新時間 22 stats uri /rabbitmq-stats #統計頁面url 23 stats realm Haproxy Manager #統計頁面密碼框上提示文本 24 stats auth admin:xxxxxx #統計頁面用戶名和密碼設置 25 stats hide-version #隱藏統計頁面上HAProxy的版本信息 26 27 listen rabbitmq_cluster 28 bind 172.28.18.104:5672 #監聽端口 29 mode tcp 30 balance roundrobin 31 server zabbix_server 172.28.18.75:5672 check inter 5000 rise 2 fall 2 32 server node1 172.28.18.103:5672 check inter 5000 rise 2 fall 2 33 server node2 172.28.18.69:5672 check inter 5000 rise 2 fall 2
退出保存,並重啟haproxy
[root@localhost haproxy-1.5-dev20]# ps -ef|grep haproxy root 23157 1 0 08:49 ? 00:00:00 haproxy -f /etc/haproxy/haproxy.conf root 23446 20907 0 08:59 pts/2 00:00:00 grep haproxy [root@localhost haproxy-1.5-dev20]# kill -9 23157 [root@localhost haproxy-1.5-dev20]# haproxy -f /etc/haproxy/haproxy.conf
此時顯示3個rabbitmq節點信息
利用下面java代碼測試負載均衡代理
package com.hl95.rabbitmq.demo; import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class Producer { public static void main(String[]args) throws IOException,TimeoutException{ ConnectionFactory factory=new ConnectionFactory(); //配置連接屬性 factory.setHost("172.28.18.104"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("admin"); factory.setPassword("xxxxxxxx"); //得到連接 Connection connection=factory.newConnection(); //創建通道 Channel channel=connection.createChannel(); //聲明(創建)隊列 String queueName="test001"; channel.queueDeclare(queueName, true, false, false, null); //發送消息 String message="你好, RabbitMQ"; for(int i=0;i<200;i++){ channel.basicPublish("",queueName, null, message.getBytes("UTF-8")); try { Thread.sleep(500); System.out.println("Consumer: "+message+"---"+i); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } channel.close(); connection.close(); } }
此時我們將客戶端連接改為172.28.18.104的前端haproxy負載均衡服務器的IP和端口,測試發送消息,后端集群節點都能同步到消息
首先執行第一次消息投遞,同時觀察104上haproxy管控台后端連接到哪個rabbitmq節點
上圖可以看到第一次消息投遞是被haproxy分配到了node1節點來接收。
繼續第二次消息投遞
上圖可以看到第二次消息投遞是被haproxy分配到了node1節點來接收。
繼續第三次
第三次消息投遞是被haproxy分配到了zabbix_server節點來接收。
繼續第四次
第四次消息投遞是被haproxy重啟分配回了node1節點來接收。驗證了負載均衡是輪詢的策略。
總共進行了4次投遞,每次200個消息,目前隊列里有800條消息待消費,3個節點的管控台隊列消息是一致的,完全復制的
至此集群搭建和負載均衡策略配置成功。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。