• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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信息,可查看到节点信息。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    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 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    访问http://192.168.119.163:25666/haproxy

    image-20211214145905612

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

    image-20211214150106143

  • 相关阅读:
    Linux系统命令——磁盘管理命令
    kuka协作机器人LBR系列 issy15R930导入到ros2_rviz(带外观文件)
    HyperTerminal 超级终端设置TCP/IP Client和TCP/IP Server
    【遍历二叉树算法描述】
    在Jupyter-lab中使用RDKit画分子2D图
    开发工程师必备————【Day09】数据库基础知识与基本SQL语句
    【高级篇】线程与线程池
    1688获得店铺详情 API 返回值说明
    Android Framework 常见解决方案(23)三方应用APP启动绑核setAffinity设置
    【数据结构】Map和Set
  • 原文地址:https://blog.csdn.net/Ajekseg/article/details/126327574