单台服务器docker如何搭建rabbitmq集群
> 1、**本文是在同一台服务器上拥有不同的docker容器,每个容器都有自己的rabbitmq服务**> 2、**这里演示3个docker,15672为主节点,15673和15674分别为从节点**
# 一、创建多个RabbitMQ容器
1、创建15672主节点容器
```shell
docker run -d --hostname rabbitmq1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management
```
2、创建15673从节点1容器
>注意15673的端口,-p 5673:5672 -p 15673:15672
```shell
docker run -d --hostname rabbitmq2 --name myrabbit2 -p 5673:5672 -p 15673:15672 --link myrabbit1:rabbit1 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management
```
3、创建15674从节点2容器1
```shell
docker run -d --hostname rabbitmq3 --name myrabbit3 -p 5674:5672 -p 15674:15672 --link myrabbit1:rabbit1 --link myrabbit2:rabbit2 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management
```
参数解释:
```shell
-d 容器后台运行
--hostname rabbitmq1 容器的主机名为 rabbitmq1,到时候从节点进行绑定的时候,需要根据这个节点名进行映射
--name myrabbit1 容器名为myrabbit1 ,在宿主机上运行“docker ps”命令时显示的名称
-p "5672:5672" 消息通讯端口,容器端口:宿主机端口
-p "15672:15672" 后台管理端口
--linkmyrabbit1:rabbit1 (必须)容器互通,相当于myrabbit2 ping 成功 myrabbit1
-e RABBITMQ_DEFAULT_USER=admin 设置rabbitmq默认用户为admin
-e RABBITMQ_DEFAULT_PASS=admin 设置rabbitmq默认密码为admin
-e RABBITMQ_ERLANG_COOKIE='rabbitcookie' 设置rabbitmq的cookie为“rabbitcookie”,可以自定义为其他文本,容器保持一致即可
--add-host="rabbitmq1":192.168.12.186(可选)修改容器内部的hosts名,即rabbitmq1对应该ip
--restart=unless-stopped docker (可选)容器重启后重启MQ
```
1. 启动完毕后,在网页打开ip:15672访问看看是否正常
2. 用户:admin
3. 密码:admin
4. **如果还访问不了,注意看一下服务器的防火墙有没有开放对应的端口!**
5. 当服务器的防火墙开放端口后,依旧访问不了,可以进入容器里面,开启rabbitMQ服务
```shell
docker exec -it myrabbit1 bash
rabbitmqctl start_app
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa7c79015fac419695277f49039db82d.png#pic_center)
> 注意:
> 1. rabbitmq的cookie也要保持一致否则建立不了集群关系
> 2. 如果是在不同的服务器,--add-host后面的参数一定要记得填写对应的ip
# 二、将RabbitMQ节点加入到集群中
1、15672主节点容器
```shell
# 命令行的形式进入myrabbit1容器
docker exec -it myrabbit1 bash
#停止当前的MQ
rabbitmqctl stop_app
#目的是清除节点上的历史数据(如果不清除,无法将节点加入到集群)
rabbitmqctl reset
#启动应用
rabbitmqctl start_app
exit
```
2、15673从节点1容器
```shell
# 命令行的形式进入myrabbit2容器
docker exec -it myrabbit2 bash
#首先停止当前MQ
rabbitmqctl stop_app
rabbitmqctl reset
#将rabbitmq2节点加入到rabbitmq1(主节点)集群当中【rabbitmq1服务器的主机名】
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
#重新启动MQ
rabbitmqctl start_app
# 退出容器
exit
#按下CTRL+Q+P 不停止运行,退出容器
```
3、15674从节点2容器
```shell
docker exec -it myrabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
exit
```
# 三、测试
1、登录主节点,ip:15672
![在这里插入图片描述](https://img-blog.csdnimg.cn/8d41b32aab744449b28ed5245c081aeb.png#pic_center)
2、在主节点15672创建交换机
![在这里插入图片描述](https://img-blog.csdnimg.cn/22f64b9ed3cb48fcbc88be6afb8a1f06.png#pic_center)
3、发现从节点15673也有该交换机
![在这里插入图片描述](https://img-blog.csdnimg.cn/807385c421a24623881b96c17706a640.png#pic_center)
4、在从接待15673创建队列,并发送消息
![在这里插入图片描述](https://img-blog.csdnimg.cn/b4416ae94c30462b98d4dde994816f1b.png#pic_center)
5、主节点15672收到消息
![在这里插入图片描述](https://img-blog.csdnimg.cn/15368bbf39704eb8b7f4cb66c8fdbee3.png#pic_center)
6、验证集群状态
```shell
root@rabbitmq1:/# rabbitmqctl cluster_status -n rabbit@rabbitmq1
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.
Cluster status of node rabbit@rabbitmq1 ...
Basics
Cluster name: rabbit@rabbitmq1
Disk Nodes
rabbit@rabbitmq1
RAM Nodes
rabbit@rabbitmq2
rabbit@rabbitmq3
Running Nodes
rabbit@rabbitmq1
rabbit@rabbitmq2
rabbit@rabbitmq3
Versions
rabbit@rabbitmq1: RabbitMQ 3.9.11 on Erlang 24.2
rabbit@rabbitmq2: on Erlang
rabbit@rabbitmq3: on Erlang
......
```
> 至此,单台服务器docker搭建rabbitmq集群完成!
# 四、在多台服务器上部署RabbitMQ集群
> 因为RabbitMQ是通过Erlang实现的,Erlang Cookie相当于不同节点之间相互通讯的秘钥,Erlang节点通过交换Erlang Cookie获得认证。
1、通过RabbitMQ容器启动日志里面的home dir路径作为根路径获取Erlang Cookie所在位置。使用:“docker logs 容器名称/ID”查看,所以Erlang Cookie的全部路径就是“/var/lib/rabbitmq/.erlang.cookie”。
2、复制Erlang Cookie到其他RabbitMQ节点
需读取其中一个节点的cookie, 并复制到其他节点(节点之间通过cookie确定相互是否可通信)。而cookie存放在/var/lib/rabbitmq/.erlang.cookie。也就说把其中一台的.erlang.cookie替换其他服务器的.erlang.cookie,其它步骤雷同单机部署方式。
- 宿主机和容器之间复制命令如下:
- 容器复制文件到宿主机:docker cp 容器名称:容器目录 物理机目录
- 宿主机复制文件到容器:docker cp 物理机目录 容器名称:容器目录
- 设置Erlang Cookie文件权限:“chmod 600 /var/lib/rabbitmq/.erlang.cookie”。
3、将节点加入集群,添加--add-host参数即可
# 五、通过nginx实现负载均衡
这里需要另外找一台服务器作为负载均衡服务器,在该服务上面随便建立一个文件夹用来存放nginx的配置文件:/home/nginx/nginx_rabbitmq.conf
文件内容:
```java
usernginx;
worker_processes1;
error_log/var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections1024;
}
http {
include /etc/nginx/mime.types;
default_typeapplication/octet-stream;
log_formatmain'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log/var/log/nginx/access.logmain;
sendfile on;
#tcp_nopush on;
keepalive_timeout65;
#gzipon;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 5s;
proxy_send_timeout 5s;
proxy_read_timeout 5s;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size64k;
proxy_temp_file_write_size 64k;
#rabbitmq管理界面
upstream rabbitManage { # 负载均衡配置,默认轮询,将客户的请求,平均分摊到下面的服务器上
server ip1主:15672;
server ip2从:15672;
server ip3从:15672;
}
server {
listen 15673;
server_nameip_nginx;# 负载均衡服务器Ip
location / {
proxy_pass http://rabbitManage;
indexindex.html index.htm;
}
}
}
# rabbitmq通信
stream{
upstream rabbitTcp{
server ip1主:5672;
server ip2从:5672;
server ip3从:5672;
}
server {
listen 5673;
server_nameip_nginx;# 负载均衡服务器Ip
location / {
proxy_pass http://rabbitTcp;
indexindex.html index.htm;
}
}
}
```
配置完毕后启动nginx:
```shell
docker run -it -d --name nginxMQ -v /home/nginx/nginx_rabbitmq.conf:/etc/nginx/nginx.conf--privileged --net=host nginx
```
启动完毕后通过负载的地址进行统一访问MQ
后台地址:ip_nginx:15673
通讯地址:ip_nginx:5673
# 六、如何给RabbitMQ容器添加用户
> 这里添加用户名test 密码 test,拥有超级管理员角色和权限
```shell
rabbitmqctl -n rabbit@rabbitmq1 add_user test test
rabbitmqctl -n rabbit@rabbitmq1 set_user_tags test administrator
rabbitmqctl -n rabbit@rabbitmq1 set_permissions -p / test ".*" ".*" ".*"
```
# 七、碰到的问题
> unable to connect to epmd (port 4369) on rabbitmq1: nxdomain (non-existing domain)
>
> 原因:不能解析rabbitmq1主机名
详细报错内容
# rabbitmqctl join_cluster rabbit@rabbitmq1
```shell
Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1
Error: unable to perform an operation on node 'rabbit@rabbitmq1'. Please see diagnostics information and suggestions below.
Most common reasons for this are:
* Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
* CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
* Target node is not running
In addition to the diagnostics info below:
* See the CLI, clustering and networking guides on https://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@rabbitmq1
* If target node is configured to use long node names, don't forget to use --longnames with CLI tools
DIAGNOSTICS
===========
attempted to contact: ['rabbit@rabbitmq1']
rabbit@rabbitmq1:
* unable to connect to epmd (port 4369) on vm-246: nxdomain (non-existing domain)
Current node details:
* node name: 'rabbitmqcli-11445-rabbit@rabbitmq2'
* effective user's home directory: /var/lib/rabbitmq
* Erlang cookie hash: NhgpfPAyGCfXaw13WdYU9w==
```
> 解决方案
vim /etc/hosts 中把各个服务器的ip和容器主机名即hostname 加上
```shell
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
ip1主 rabbitmq1
ip2从 rabbitmq2
ip3从 rabbitmq3
```
注意:一定不要加上`rabbit@` ,比方说我之前配成 ip1主 rabbit@rabbitmq1
> 小结
如果采用多机部署方式,需读取其中一个节点的cookie, 并复制到其他节点(节点之间通过cookie确定相互是否可通信)。而cookie存放在/var/lib/rabbitmq/.erlang.cookie。也就说把其中一台的.erlang.cookie替换其他服务器的.erlang.cookie,其它步骤雷同单机部署方式。
原文链接
写得好。我选择rocketmq 挺好的 支持一下 新手学起来 不错 但是我友情提示一下(不是杠,不是挑刺)单机部署最好做成docker-compose 一键部署 谢谢楼主,支持分享,正需要用 不错学习了
跟着学习一下! damon911 发表于 2022-7-28 11:00
不错 但是我友情提示一下(不是杠,不是挑刺)单机部署最好做成docker-compose 一键部署
同意,我一般也这样 那这个挂了是不是等于集群全挂
页:
[1]