Docker builds RabbitMQ+HAProxy

RabbitMQ

This article uses Docker to build a RabbitMQ cluster, then uses HAProxy for load balancing, and finally uses KeepAlived to achieve high availability of the cluster, thus building a RabbitMQ high availability load balancing cluster. Limited by its own conditions, this article uses the clone function of VMware virtual machine to clone two servers for operation. It is only used as a demo and can be adjusted according to the actual situation during development.

First look at what the RabbitMQ high availability load balancing cluster looks like:

image-20211214093818322

Using Docker to build a RabbitMQ high-availability load balancing cluster is roughly divided into three steps:

  1. Start multiple (3 as an example) RabbitMQ, build a RabbitMQ cluster, and configure it in mirror mode.
  2. Use HAProxy for load balancing.
  3. Use KeepAlived to achieve high availability.

1. Build a RabbitMQ cluster

The biggest problem with building multiple physical machines is that in the default bridge network mode, the docker container uses the subnet IP dynamically allocated by the bridge according to the DHCP protocol. The container is a virtual network container, which is isolated from the external network, so it cannot be resolved through hosts External IP, there is no way to connect to other mq nodes

The current known construction modes of multi-homed clusters are:
① Host network mode (- -net host)
② Plug-in (Calico flannel weave Docker Overlay)
③ Overlay network mode
④ Intranet DNS server provides domain name resolution

Here it is built on a virtual machine, and then build multiple hosts when there is time

Start 3 RabbitMQ nodes using Docker:

1. Pull the image

# 由于我是内网,所以我找了一台外网机器拉取后,打包上传到了内网虚机中
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. Make the remaining two nodes join the cluster

–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. Configure the mirror queue

Follow the steps below to view the queue +2display

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

Replenish:

tcp 4369 port is used for cluster neighbor discovery;
tcp 5671, 5672 ports are used for AMQP 0.9.1 and 1.0 clients;
tcp 15672 port is used for http api and rabbitadmin access, the latter only when the management plugin is enabled;
tcp 25672 port is used Distributed node/tool ​​communication in erlang

Notice:

1. The full name of the node defaults to [node name@host name]
2. Assuming that the full name of node 1 to be joined by node 2 (hr02) is [rabbit@rabbit1], rabbitmq will first search for the existence of the node on the same network segment/bridge If the node does not exist, it will search for the ip corresponding to rabbit1 in the hosts configured on node 2, and connect through port 4369. If the connection is successful, node 2 will inform the other party that the name of the node that node 2 wants to connect to is [rabbit@rabbit1], and the other party will search for the node locally according to the full name of [rabbit@rabbit1] 3. If node
1 The host name of the host is localhost, even if the mapping relationship [rabbit1-target ip] is configured in the hosts of node 2, the node [rabbit@rabbit1] cannot be searched on node 1, because the real node name of node 1 is [rabbit @localhost】

2. Join 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

Visit http://192.168.119.163:25666/haproxy

image-20211214145905612

Access: http://192.168.119.163:15666/#/

image-20211214150106143

Guess you like

Origin blog.csdn.net/YourMr/article/details/122679175