吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1945|回复: 8
收起左侧

[其他转载] 单台服务器docker如何搭建rabbitmq集群

[复制链接]
Wisdom_xiaogui 发表于 2022-7-28 10:23

1、本文是在同一台服务器上拥有不同的docker容器,每个容器都有自己的rabbitmq服务
2、这里演示3个docker,15672为主节点,15673和15674分别为从节点

一、创建多个RabbitMQ容器

1、创建15672主节点容器

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

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

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

参数解释:

-d 容器后台运行

--hostname rabbitmq1 容器的主机名为 rabbitmq1,到时候从节点进行绑定的时候,需要根据这个节点名进行映射

--name myrabbit1 容器名为myrabbit1 ,在宿主机上运行“docker ps”命令时显示的名称

-p "5672:5672" 消息通讯端口,容器端口:宿主机端口

-p "15672:15672" 后台管理端口

--link  myrabbit1: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服务

docker exec -it myrabbit1 bash
rabbitmqctl start_app

在这里插入图片描述

注意:

  1. rabbitmq的cookie也要保持一致否则建立不了集群关系
  2. 如果是在不同的服务器,--add-host后面的参数一定要记得填写对应的ip

二、将RabbitMQ节点加入到集群中

1、15672主节点容器

# 命令行的形式进入myrabbit1容器
docker exec -it myrabbit1 bash
#停止当前的MQ
rabbitmqctl stop_app
#目的是清除节点上的历史数据(如果不清除,无法将节点加入到集群)
rabbitmqctl reset
#启动应用
rabbitmqctl start_app
exit

2、15673从节点1容器

# 命令行的形式进入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容器

docker exec -it myrabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
exit

三、测试

1、登录主节点,ip:15672

在这里插入图片描述

2、在主节点15672创建交换机

在这里插入图片描述

3、发现从节点15673也有该交换机

在这里插入图片描述

4、在从接待15673创建队列,并发送消息

在这里插入图片描述

5、主节点15672收到消息

在这里插入图片描述

6、验证集群状态

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
文件内容:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$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.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    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_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage { # 负载均衡配置,默认轮询,将客户的请求,平均分摊到下面的服务器上
        server ip1主:15672;
        server ip2从:15672;
        server ip3从:15672;
    }
    server {
        listen       15673;
        server_name  ip_nginx;  # 负载均衡服务器Ip
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  
    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server ip1主:5672;
        server ip2从:5672;
        server ip3从:5672;
    }

    server {
        listen       5673;
        server_name  ip_nginx;  # 负载均衡服务器Ip 
        location / {  
            proxy_pass   http://rabbitTcp;
            index  index.html index.htm;  
        } 
    }
}

配置完毕后启动nginx:

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,拥有超级管理员角色和权限

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主机名

详细报错内容
[root@rabbitmq2 ~]# rabbitmqctl join_cluster rabbit@rabbitmq1

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 加上

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,其它步骤雷同单机部署方式。

原文链接

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
小小学生 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Js_Aaron 发表于 2022-7-28 10:42
写得好。我选择rocketmq
小小学生 发表于 2022-7-28 10:53
damon911 发表于 2022-7-28 11:00
不错 但是我友情提示一下(不是杠,不是挑刺)单机部署最好做成docker-compose 一键部署
zjlpsw 发表于 2022-7-28 11:13
谢谢楼主,支持分享,正需要用
a22488 发表于 2022-7-28 11:15
不错学习了
photocs 发表于 2022-7-28 11:54
跟着学习一下!
tencentma 发表于 2022-7-28 14:09
damon911 发表于 2022-7-28 11:00
不错 但是我友情提示一下(不是杠,不是挑刺)单机部署最好做成docker-compose 一键部署

同意,我一般也这样
956495971 发表于 2022-7-28 15:58
那这个挂了是不是等于集群全挂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 03:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表