Docker搭建RabbitMQ+HAProxy

RabbitMQ

本文使用Docker搭建RabbitMQ集群,然后使用HAProxy做负载均衡,最后使用KeepAlived实现集群高可用,从而搭建起来一个完成了RabbitMQ高可用负载均衡集群。受限于自身条件,本文使用VMware虚拟机的克隆功能克隆了两台服务器进行操作,仅作为一个demo,开发中可根据实际情况进行调整。

首先看下RabbitMQ高可用负载均衡集群长什么样子:

image-20211214093818322

使用Docker构建RabbitMQ高可用负载均衡集群大概分为三个步骤:

  1. 启动多个(3个为例)RabbitMQ,构建RabbitMQ集群,并配置为镜像模式。
  2. 使用HAProxy做负载均衡。
  3. 使用KeepAlived实现高可用。

一、构建RabbitMQ集群

多物理机搭建最大的问题是,默认bridge网络模式下docker容器使用的是bridge按照DHCP协议动态分配的子网IP,容器是虚拟网络容器,相对于外部网络是隔离的,所以无法通过hosts解析到外部IP,也无从连接其他mq节点

多宿主集群当前已知的搭建模式有:
① host的网络模式(- -net host)
② 插件(Calico flannel weave Docker Overlay)
③ overlay的网络模式
④ 内网DNS服务器提供域名解析

这里采用为一台虚机上面搭建,后面有时间了再搭建多主机

使用Docker启动3个RabbitMQ节点:

1.拉取镜像

# 由于我是内网,所以我找了一台外网机器拉取后,打包上传到了内网虚机中
docker pull rabbitmq:management
docker save rabbitmq:management > rabbitmq.tar

# 启动并创建三个同样cookie的镜像实例(同样的cookie才能加入集群)
# 192.168.119.163
docker run -itd --restart=always --hostname rabbit1 --name rabbitmq1 -v /data/rabbitMQ/rabbit1:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:management

docker run -itd --restart=always --hostname rabbit2 --name rabbitmq2 -v /data/rabbitMQ/rabbit2:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmq1:rabbit1 rabbitmq:management

docker run -itd --restart=always --hostname rabbit3 --name rabbitmq3 -v /data/rabbitMQ/rabbit3:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmq1:rabbit1 --link rabbitmq2:rabbit2  rabbitmq:management

# 配置hosts
192.168.119.163 rabbit1
192.168.119.163 rabbit2
192.168.119.163 rabbit3

2.使其余两个节点加入集群

–ram 设置rabbitmq为内存存储模式
–disc 设置rabbitmq为硬盘存储模式

# 这里设置为内存存储模式
# 进入第一个rabbitmq节点容器:
docker exec -it rabbitmq1 bash
# 进入容器后,操作rabbitmq,执行如下命令:
[root@orderer rabbitMQ]# docker exec -it rabbitmq1 bash
root@rabbit1:/# rabbitmqctl stop_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Stopping rabbit application on node rabbit@rabbit1 ...
root@rabbit1:/# rabbitmqctl reset
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Resetting node rabbit@rabbit1 ...
root@rabbit1:/# rabbitmqctl start_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Starting node rabbit@rabbit1 ...
root@rabbit1:/# exit
exit

# 使rabbitmq2加入rabbitmq1节点
[root@orderer rabbitMQ]# docker exec -it rabbitmq2 bash
root@rabbit2:/# rabbitmqctl stop_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Stopping rabbit application on node rabbit@rabbit2 ...
root@rabbit2:/# rabbitmqctl reset
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Resetting node rabbit@rabbit2 ...
root@rabbit2:/# rabbitmqctl join_cluster --ram rabbit@rabbit1
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Clustering node rabbit@rabbit2 with rabbit@rabbit1
root@rabbit2:/# rabbitmqctl start_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Starting node rabbit@rabbit2 ...
root@rabbit2:/# exit
exit

# 进入第三个rabbitmq节点容器,执行如下命令
[root@orderer rabbitMQ]# docker exec -it rabbitmq3 bash
root@rabbit3:/# rabbitmqctl stop_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Stopping rabbit application on node rabbit@rabbit3 ...
root@rabbit3:/# rabbitmqctl reset
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Resetting node rabbit@rabbit3 ...
root@rabbit3:/# rabbitmqctl join_cluster --ram rabbit@rabbit1
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Clustering node rabbit@rabbit3 with rabbit@rabbit1
root@rabbit3:/# rabbitmqctl start_app
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Starting node rabbit@rabbit3 ...
root@rabbit3:/# exit
exit

# 命令介绍
#关闭应用
rabbitmqctl stop_app
#清除所有队列
rabbitmqctl reset
#加入节点
rabbitmqctl join_cluster --ram rabbit@rabbit1    # @后主机名
#启动应用
rabbitmqctl start_app
#查看集群状态
rabbitmqctl cluster_status
# 从rabbit@rabbit1主节点上移除rabbit@rabbit3节点
rabbitmqctl -n rabbit@rabbit1 forget_cluster_node rabbit@rabbit3


# 执行上述操作,这时候 再查看 http://192.168.119.163:15672的overview面板中的Nodes信息,可查看到节点信息。

image-20211214141154752

3.配置镜像队列

按如下操作,查看队列显示+2即可

root@rabbit1:/# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...
root@rabbit1:/# rabbitmqctl set_permissions -p / guest ".*" ".*" ".*"
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Setting permissions for user "guest" in vhost "/" ...
root@rabbit1:/# rabbitmqadmin -H192.168.119.163 -P15672 -uguest -pguest declare queue --vhost=/ name=q.test durable=true
queue declared

说明:

在cluster中任意节点启用策略,策略会自动同步到集群节点
1 rabbitmqctl set_policy-p/ha-all"^"’{“ha-mode”:“all”}’
这行命令在vhost名称为hrsystem创建了一个策略,策略名称为ha-allqueue,策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。

image-20211214142655512

补充:

tcp 4369 端口用于集群邻居发现;
tcp 5671,5672 端口用于AMQP 0.9.1 and 1.0 clients使用;
tcp 15672 端口用于http api与rabbitadmin访问,后者仅限在management plugin开启时;
tcp 25672 端口用于erlang分布式节点/工具通信

注意:

1、节点的全称默认为 【节点名字@主机名称】
2、假定节点2(hr02)要加入的节点1的全称是【rabbit@rabbit1】,rabbitmq首先会在同一网段/桥下寻找是否存在该节点,如果不存在,会在节点2配置的hosts中寻找rabbit1对应的ip,通过4369端口进行连接。如果连接成功,节点2会告知对方,节点2想要连接的对方的节点的名称是【rabbit@rabbit1】,对方则会按照【rabbit@rabbit1】的全名在本地进行节点搜索
3、 如果节点1的主机名称为localhost,那即使在节点2的hosts配置了【rabbit1- 目标ip】的映射关系,在节点1也无法搜索到【rabbit@rabbit1】这个节点,因为节点1的真实节点名称是【rabbit@localhost】

二、加入Haproxy

# 因为前面搭建了redis高可用,已经启动了haproxy,加入参数即可
vim haproxy/haproxy.cfg
#负载均衡的名字(自定义)
#监听5666端口并转发到rabbitmq服务
listen rabbitmq_cluster
  bind 0.0.0.0:5666 #对外提供的虚拟的端口
  option tcplog
  mode tcp
  #负载均衡算法为轮询
  balance roundrobin
  #对后端服务器的健康状况检查间隔为2000毫秒,
  #连续2次健康检查成功,则认为是有效的,连续3次健康检查失败,则认为服务器宕机
  server rabbitmq1 192.168.119.163:5672 check inter 5000ms rise 2 fall 3
  server rabbitmq2 192.168.119.163:5673 check inter 5000ms rise 2 fall 3
  server rabbitmq3 192.168.119.163:5674 check inter 5000ms rise 2 fall 3

#haproxy的客户页面
listen http_front
  bind 0.0.0.0:25666
  stats uri /haproxy #页面地址
  #页面的用户名和密码,建议主备设为不同,方便确定抢占到VIP的服务器是主机还是备机
  stats auth admin:admin
  stats admin if TRUE #管理界面,成功登陆后可通过webui管理节点

#rabbit管理页面,监听15666端口转发到rabbitmq的客户端
listen rabbitmq_admin
  bind 0.0.0.0:15666
  server rabbitmq1 192.168.119.163:15672 check inter 5000ms rise 2 fall 3
  server rabbitmq2 192.168.119.163:15673 check inter 5000ms rise 2 fall 3
  server rabbitmq3 192.168.119.163:15674 check inter 5000ms rise 2 fall 3

访问http://192.168.119.163:25666/haproxy

image-20211214145905612

访问:http://192.168.119.163:15666/#/

image-20211214150106143

你可能感兴趣的:(java,java-rabbitmq,rabbitmq,docker,java,后端)