DockerCompose部署RabbitMQ集群

DockerCompose部署RabbitMQ集群

最近小黄在工作中正好需要部署RabbitMQ集群,借此来记录一下,也希望可以帮助到大家

前置条件

简单介绍一下咱们公司现有的条件以及想要达成的效果

服务器3台,3台都是属于一个专有网络中,也就是说3台机子形成局域网,可以互相访问

  • ServerA:有公网ip的服务器,可以访问公网
  • ServerB:只有私网的服务器,需要通过ServerA来访问公网
  • ServerC:同ServerB

因为ServerA的内存占用已经比较高了,所以小黄的想法是在ServerB、ServerC上各部署一个RabbitMQ形成集群,因为程序也是跑在局域网中,所以不需要向外暴露5672端口,只需要在ServerA上通过反向代理暴露15672端口即可

修改hosts文件,让他们通过ServerA这种命名的方式访问各自的ip

172.16.0.130 ServerA
172.16.0.131 ServerB
172.16.0.132 ServerC

部署RabbitMQ

小黄采用的是DockerCompose方式部署,这里刚开始小黄就踩坑了

拉镜像

因为ServerB、ServerC没办法直接去docker仓库拉镜像,所以需要在ServerA上拉镜像在传到私网服务器上

# ServerA上执行
# 拉镜像,这里要注意的是,一定要拉management,只有management才有可视化管理页面的插件
docker pull rabbitmq:management

# 导出镜像
docker save -o rabbitmq.tar rabbitmq:management

# 发送文件到ServerB、ServerC
rsync -av /root/docker-images/rabbitmq.tar ServerB:/root

# ServerB、ServerC上执行
docker load -i rabbitmq.tar

docker-compose.yml

接下来需要编写docker-compose.yml文件,以ServerB来介绍,ServerC只是需要讲ServerB修改成ServerC即可

version: "3.2"
services:
  rabbitmq:
    image: rabbitmq:management
    container_name: rabbitmq
    restart: on-failure:5
    # 对应host文件
    hostname: ServerB
    # 这个是向容器内部添加hosts文件,这里需要与ServerC形成集群,所以要写ServerC的地址
    extra_hosts:
      - "ServerC:172.16.0.132"
    ports:
      - "4369:4369"
      - "5672:5672"
      - "15672:15672"
      - "25672:25672"
    volumes:
      - ./data:/var/lib/rabbitmq
      - ./erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin
      - RABBITMQ_NODENAME=rabbit@ServerB # 节点名称
    networks:
      - rabbitmq-network

networks:
  rabbitmq-network:
    driver: bridge

接下来要解释几个关键信息

暴露端口

5672、15672就不介绍了,这里注意安全组得开放这些端口,出方向、入方向都需要

  • 4369:这是 Erlang 分布式节点之间通信的 epmd(Erlang Port Mapper Daemon)端口。epmd 是一个用于管理 Erlang 节点之间通信的守护进程,它负责维护一个节点注册表,以便其他节点可以发现和连接到正在运行的节点。在 RabbitMQ 集群中,节点之间使用 epmd 来进行通信和发现。
  • 25672:这是 RabbitMQ 节点之间的 AMQP 0-9-1 协议端口。在 RabbitMQ 集群中,节点之间使用此端口进行内部通信,包括集群节点之间的消息传递和状态同步。

.erlang.cookie

.erlang.cookie存储了一串密钥,这个可以自定义,需要加入相同的集群,就需要里面的编码一致,我这边采取挂载的方式来修改,也可以进入容器内部修改

搭建集群

在ServerB、ServerC上启动RabbitMQ,在mq中是不存在主节点、子节点的关系的,但我还是比较习惯这样称呼,目前讲ServerB作为主节点,ServerC来主动加入该集群成为子节点

# 进入ServerC上的容器
docker exec -it rabbitmq /bin/bash

rabbitmqctl stop_app
rabbitmqctl reset
# 加入集群,rabbit@ServerB要对应上面设置的RABBITMQ_NODENAME
# --ram将消息存储在内存中,不加则存储在磁盘空间,这取决于个人
rabbitmqctl join_cluster --ram rabbit@ServerB
rabbitmqctl start_app

执行完之后,就可以查看集群信息

rabbitmqctl cluster_status

看到这个输出,集群就搭建成功了

image-20231214105111561

测试

在ServerB上创建队列、交换机、绑定关系并且发送信息,在ServerC上也可以获取到这些信

# 执行这些操作前,需要向创建用户、授予权限
# 创建新用户
rabbitmqctl add_user your_username your_password

# 授予管理员权限
rabbitmqctl set_user_tags your_username administrator

# 授予访问虚拟主机的权限
rabbitmqctl set_permissions -p / your_username ".*" ".*" ".*"

# 创建队列
rabbitmqadmin declare queue name=<队列名称> --username=username --password=password

# 创建交换机
rabbitmqadmin declare exchange name=<交换机名称> type=<交换机类型> --username=username --password=password

# 绑定队列到交换机
rabbitmqadmin declare binding source=<交换机名称> destination=<队列名称> routing_key=<路由键> --username=username --password=password

# 向交换机发送消息
rabbitmqadmin publish exchange=your_exchange_name routing_key=your_routing_key payload="Your message content" --username=username --password=password

# 查看队列中的消息
rabbitmqadmin get queue=your_queue_name --username=username --password=password

在小黄的一系列测试中,发现一个问题,向ServerB中发送消息后,消息其实是存在ServerB上的,ServerC上并没有存储该消息的内容

也就是说现在的集群只能做到一部分的功能,当程序连接到某一个RabbitMQ节点时,他会自动发现集群,加入到集群中,当ServerB挂掉之后,ServerC可以继续承担消息收发的功能,当时ServerB挂掉之前假如队列中有消息没处理完,那这些消息将不复存在,也就是说会出现消息丢失的情况

镜像队列

  • 优点:镜像队列会将队列中的消息在集群中的多个节点之间进行复制。这样,无论消息最初被发送到哪个节点,它都会被复制到其他节点上,确保即使某个节点发生故障,消息仍然可以被其他节点消费,提供冗余和高可用性

  • 缺点:资源消耗

使用正则表达式"^myqueue.*"来匹配myqueue开头的队列

rabbitmqctl set_policy ha-all "^myqueue.*" '{"ha-mode":"all"}' --priority 0 --apply-to queues

如果设置所有队列都为镜像队列

rabbitmqctl set_policy ha-all ".*" '{"ha-mode":"all"}' --apply-to queues

再次测试,发现ServerB即使挂掉,还是可以从ServerC上读取数据

反向代理

我们还是用docker compose的方式来部署nginx,只暴露我们需要的端口

version: "3.2"
services:
  nginx:
    image: nginx:stable-perl
    container_name: nginx-middleware
    user: root
    privileged: true
    ports:
      - "15672:15672"
    volumes:
      - /root/nginx-middleware/html:/usr/share/nginx
      - /root/nginx-middleware/conf/nginx.conf:/etc/nginx/nginx.conf
      - /root/nginx-middleware/log:/var/log/nginx
    environment:
      - TZ=Asia/Shanghai
      - LANG=C.UTF-8
      - LC_ALL=C.UTF-8
    networks:
      nginx-middleware:
        aliases: 
          - nignx-ware
    logging:
      driver: "json-file"
      options:
        max-size: "30m"

networks:
  nginx-middleware: 
    external: true

nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        listen 15683;
        server_name 外网ip;

        location / {
            proxy_pass http://私网服务器ip:15672;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

这里有一个很坑的点,记录一下,当时配的proxy_pass http://私网服务器ip:15672/,因为结尾多了一个斜杠,导致只能访问管理页面主界面,其他请求全都是404

小Tip

必须要保证安全组开放了15672端口,授权对象0.0.0.0

之前小黄只是授权了私网ip可以访问,导致telnet访问不不通

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/244234.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

100V耐压 内置MOS ESOP8 40V输入 转5V 2.1A恒压输出

100V耐压内置MOS ESOP8 40V输入转5V 2.1A恒压输出 芯片测试数据如下图&#xff1a;

SAHI强化YOLOv5在小目标上的表现

文章目录 环境前言安装sahiyolov5检测sahi添加新的检测模型 环境 ubuntu 18.04 64bitsahi 0.8.4yolov5 5.0pytorch 1.7.1cu101 前言 目标检测和实例分割是迄今为止计算机视觉中最重要的应用领域&#xff0c;各种目标检测网络层出不穷&#xff0c;然而&#xff0c;小目标的检…

用23种设计模式打造一个cocos creator的游戏框架----(十六)亨元模式

1、模式标准 模式名称&#xff1a;亨元模式 模式分类&#xff1a;结构型 模式意图&#xff1a;运用共享技术有效地支持大量细粒度的对象 结构图&#xff1a; 适用于&#xff1a; 1、一个应用程序使用了大量的对象. 2、完全由于使用大量的对象&#xff0c;造成很大的存储开…

人工智能改变医疗保健:人工智能如何革命医学

人工智能&#xff08;Artificial Intelligence, 简称AI&#xff09;的快速发展正逐渐改变着我们的生活方式和社会结构。在医疗保健领域&#xff0c;AI的应用不仅提供了更准确、高效的诊断和治疗手段&#xff0c;还为医生和患者之间的交流提供了新的途径。本文将探讨人工智能如何…

java springboot+jsoup写一段爬虫脚本 将指定地址的 图片链接 文本 超链接地址存入自己的属性类对象中

首先 还是最基本的 要在 pom.xml 引入依赖 <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.1</version> </dependency>然后 我们可以在项目中创建一个属性类 我这里就叫 WebContent了…

到底什么是DevOps

DevOps不是一组工具&#xff0c;也不是一个特定的岗位。在我看来DevOps更像是一种软件开发文化&#xff0c;一种实现快速交付能力的手段。 DevOps 强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理&#xff0c;从而更快、更频繁地交付更稳定的…

微信这个地方,收费了

大家好&#xff0c;我是小悟 我们都知道&#xff0c;微信企业类型小程序需要认证&#xff0c;现在微信个人小程序也需要认证了&#xff0c;账号逾期未完成微信认证&#xff0c;将影响账号“被搜索”能力。 这一要求&#xff0c;在很多人看来可能是一项不必要的规定。然而&…

数据结构之---- 图

数据结构之---- 图 什么是图&#xff1f; 图是一种非线性数据结构&#xff0c;由顶点和边组成。我们可以将图 &#x1d43a; 抽象地表示为一组顶点 &#x1d449; 和一组边 &#x1d438; 的集合。 以下示例展示了一个包含 5 个顶点和 7 条边的图。 如果将顶点看作节点&…

【全面解读】洁净室验收及检测设备、方法全介绍

洁净室相关概念 洁净室又可称作无尘室&#xff08;Cleanroom&#xff09;&#xff0c;通常用作专业工业生产或科学研究的一部分&#xff0c;包括制造药品&#xff0c;集成电路&#xff0c;CRT&#xff0c;LCD&#xff0c;OLED和microLED显示器等。洁净室的设计是为了保持极低水…

数据结构之---- 堆、建堆操作、Top‑K 问题

数据结构之---- 堆、建堆操作、Top‑K 问题 什么是堆&#xff1f; 堆是一种满足特定条件的完全二叉树 主要可分为两种类型&#xff1a; 大顶堆&#xff1a;任意节点的值 ≥ 其子节点的值。小顶堆&#xff1a;任意节点的值 ≤ 其子节点的值。 堆作为完全二叉树的一个特例&am…

闲人闲谈PS之四十八——非标定制企业BOM传输问题

惯例闲话&#xff1a;上个月&#xff0c;集团公司组织了一次信息化大会&#xff0c;邀请国内外10几位知名的院士嘉宾来助阵。能听这些站在知识顶端的大佬的讲座&#xff0c;受益匪浅。至少在当下数字化趋势之下&#xff0c;细分领域的发展势头&#xff0c;有了方向性的指点。很…

C++怎么快速提升实力?

C怎么快速提升实力&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&…

什么是持续测试?为什么要持续测试?

测试是软件开发生命周期 (SDLC) 的重要组成部分。SDLC 的每个阶段都应包含测试&#xff0c;以获得更快的反馈并提高产品质量。 我们来聊聊持续测相关话题&#xff0c;如何从持续测试中获得更大的收益。 何谓持续测试 持续测试有助于在软件开发生命周期 (SDLC) 的所有阶段提供…

本地连锁门店经营可以借助系统实现哪些功能?

不少的连锁门店目前还是很基础的ERPPOS收银&#xff0c;其他的还是走传统的手工管理&#xff0c;大多连锁老板知道借助信息化系统可以帮助门店实现精细化管理&#xff0c;提高运营效率&#xff0c;降低成本&#xff0c;增强竞争力&#xff0c;但不知道怎么去做&#xff0c;能做…

快速搭建知识付费平台?我有才,为你提供一站式解决方案

在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和维护一个属于自己的知识付费平台需要…

《Java 已死、前端已凉》 我的评价是:中肯的

《Java 已死、前端已凉》 我的评价是&#xff1a;中肯的 如题所述 此次包含了前端、后端开发 以下为论述&#xff1a; 文章目录 前端后端当前环境附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什么是大端和小端数据传输中的大…

vscode 文件目录栏缩进

一个好的开发IDE&#xff0c;一定是让人赏心悦目的&#xff0c;这个赏心悦目也一定是包含层级目录的清晰明了&#xff01;不能像感冒的鼻涕一样一擤一摊子&#xff01;就像。。。。嗯&#xff0c;算了&#xff0c;断子还是不讲了&#xff0c;怕有些妹子投诉 或发消息批评我。。…

c++原子变量

原子变量 概述 ​ C11提供了一个原子类型std::atomic<T>&#xff0c;通过这个原子类型管理的内部变量就可以称之为原子变量&#xff0c;我们可以给原子类型指定bool、char、int、long、指针等类型作为模板参数&#xff08;不支持浮点类型和复合类型&#xff09;。 ​ …

如何用gpt改写文章 (1) 神码ai

大家好&#xff0c;今天来聊聊如何用gpt改写文章 (1)&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 如何用GPT改写文章 一、引言 随着人工智能技术的飞速发展&#xff0c;自然语言处理领域取得了重大突…

【一步到位】汽车过户全攻略:轻松搞定,告别繁琐流程

校长车行是一家昆明二手车代办公司&#xff0c;今天我们要聊一聊一个让很多人头疼的问题——汽车过户。相信很多朋友在购买二手车或者需要将车辆转让给他人时&#xff0c;都会遇到这个繁琐的流程。那么&#xff0c;如何才能轻松搞定汽车过户呢&#xff1f;接下来&#xff0c;就…