rabbitmq集群搭建
前期准备
从官网下载的rabbitmq是最原始的,需要进行一些设置
- 启动rabbitmq镜像
docker run -it -P rabbitmq /bin/bash
- 更换源,为了更好的安装软件
文件位置:/etc/apt/sources.list
文件内容:
deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverseroot
- 安装vim
apt-get update apt-get install vim
- 开启web_stomp插件
rabbitmq-plugins enable rabbitmq_web_stomp
- 将此容器提升为镜像
docker commit -m="myrabbitmq" -a="yao" rabbitmq myrabbitmq
运行起来 三个rabbitmq
docker run -d -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' -p 5673:5672 -p 15673:15672 -p 15677:15674 --name rabbitmq1 --hostname rabbit1 myrabbitmq
docker run -d -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' -p 5674:5672 -p 15675:15672 -p 15678:15674 --name rabbitmq2 --hostname rabbit2 myrabbitmq
docker run -d -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' -p 5675:5672 -p 15676:15672 -p 15679:15674 --name rabbitmq3 --hostname rabbit3 myrabbitmq
- 15672:web管理的端口映射。
- 15674:web_stomp所用端口的映射
- 5672:Java client tcp连接端口所用映射。
修改三个rabbitmq的hosts文件,使一样
文件位置:/etc/hosts
文件内容:如下
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 rabbit1
172.17.0.3 rabbit2
172.17.0.4 rabbit3
修改rabbitmq的erlangcookie,使一样
文件位置:/var/lib/rabbitmq/.erlang.cookie
以其中一个节点文件为准,复制到另外两个节点。
docker cp 宿主机路径 容器id:容器路径 docker cp 容器id:容器路径 宿主机路径
其实,由同一个镜像运行过得三个rabbitmq实例,并且指定了环境变量RABBITMQ_ERLANG_COOKIE='rabbitcookie',会发现,三个节点的erlangcookie本来就一样
加入集群
以rabbit1作为主节点。将rabbit2、rabbit3加入到集群rabbit@rabbit1中。
在rabbit2节点做如下操作:
#首先把rabbit2节点的rabbitmq停止
rabbitmqctl stop_app
#将rabbit2这个节点加入集群
rabbitmqctl join_cluster --ram rabbit@rabbit1
#启动服务
rabbitmqctl start_app
#查看集群现状
rabbitmqctl cluster_status
在rabbit3节点上一样的操作。
镜像队列
对于有的队列为了提高可靠性,可以使用镜像队列。使用如下命令:
#将以data开头的队列镜像到集群中所有节点
rabbitmqctl set_policy exceptionpolicy "^data" '{"ha-mode":"all"}'
至此一个普通的集群建立完成。使用端口测试成功。虽说这样可以把三个节点当一个节点用,但是客户端(生产者、消费者)还是连接的某一个节点的端口。但这个节点崩溃,系统还是会崩溃。
为此使用HAproxy做一个代理及负载均衡。
HAProxy
- 从docker hub pull一个官方镜像
docker pull 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 http
option httplog
option dontlognull
retries 3
option abortonclose
maxconn 4096
timeout connect 5000ms
timeout client 10000ms
timeout server 5000ms
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
mode tcp
option tcplog
server rabbit1 172.17.0.2:5672
server rabbit2 172.17.0.3:5672
server rabbit3 172.17.0.4:5672
listen rabbitmq_cluster
bind 0.0.0.0:8101
mode http
option httplog
balance roundrobin
server rabbit1 172.17.0.2:15674 check inter 5000 rise 2 fall 3
server rabbit2 172.17.0.3:15674 check inter 5000 rise 2 fall 3
server rabbit3 172.17.0.4:15674 check inter 5000 rise 2 fall 3
- 运行haproxy
docker run -it --hostname myhaproxy --name myhaproxy -p 8101:8101 -p 8102:8102 -v e:/containerfile/haproxyvolumn/:/usr/local/etc/haproxy/ haproxy
#-v 数据卷映射。因为haproxy镜像默认没有haproxy.cfg文件,而他的dockerfile最后一句是需要访问这个文件,所以需要在宿主机新建配置文件,然后通过数据卷的方式更新到容器。
- 运行haproxy
haproxy -f haproxy.cfg
这样起到的效果是:rabbitmq客户端(生产者、消费者)不用再和集群中的某一个节点建立连接了,而是通过了haproxy。
e.g:之前需要和特定的节点(如rabbit3: localhost:5675)建立连接,当这个节点崩溃,则客户端断开连接。这样的系统是很不稳定的。
使用haproxy之后,只需要使用(localhost:8102)去建立连接,具体是和哪一个节点建立连接,有haproxy确定。而且当其中一个节点崩溃,也不影响系统,因为haproxy会选择剩下的节点。
存在的问题:
- 微信小程序建立连接一段时间后自动断开。(已解决)
在微信小程序设置incoming心跳。(有可能不是因为这个而解决的。————————确实不是。为0也可以) - 微信小程序(testsendmessage)在建立连接(8101)时,第一次不成功,第二次才能成功
- java客户端在发送消息时,第一次不行,当可以后,发两次后就建立不了连接了。过一会儿就有可以建立连接了,不知为何。
- 上述问题导致其中一个节点(haproxy本来选择的节点)崩溃后,haproxy由于要选择剩余两个节点,客户端需要刷新,这就相当于重新开始,就又遇到1、2的问题。
- 如果一个队列,创建它的节点崩溃后,还能否正常工作?
猜测:应该不能,不过如果是镜像模式或许可以。 - 还未正式测试加入exchange的rabbitmq集群消息推送。