DockerCompose部署RabbitMQ集群

news2024/9/21 7:29:03

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访问不不通

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UDP特性之广播

UDP特性之广播 1. 广播的特点2. 设置广播属性3. 广播通信流程4. 通信代码总结 1. 广播的特点 广播的UDP的特性之一&#xff0c;通过广播可以向子网中多台计算机发送消息&#xff0c;并且子网中所有的计算机都可以接收到发送方发送的消息&#xff0c;每个广播消息都包含一个特殊…

单机环境下一人一单

优惠券秒杀 添加优惠卷 店铺发布优惠券又分为平价券和特价券, 平价券可以任意购买而特价券需要秒杀抢购(限制数量和时间) tb_voucher(平价券): 优惠券的基本信息 tb_seckill_voucher(秒杀券): 有voucher_id字段表示具有优惠卷的基本信息,此外还有库存,开始抢购时间,结束抢购…

世界第一个语言不通的人是如何沟通的?

引言&#xff1a;语言是人类交流的重要工具&#xff0c;但在人类历史的某个时刻&#xff0c;肯定会有这样一位勇敢的先驱&#xff0c;他成为了世界上第一个语言不通的人。那么在他面临交流难题时&#xff0c;他是如何与他人沟通的呢&#xff1f;本文将对此进行探索。主体&#…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 单体gltf模型与Blender中的方向对应关系

作者&#xff1a;taco 在很多包含动画的场景中&#xff0c;像模拟小人的行走、模拟火车的轨迹运行&#xff0c;又或者是模拟风力发电等等等。我们通常会加一些动画模型到里面。而有的时候可能会出现&#xff0c;这火车怎么倒着走啊&#xff01;这人怎么头朝下啊。这种方向的问题…

【MySQL】MySQL库的增删查改

文章目录 1.库的操作1.1创建数据库1.2创建数据库案例 2.字符集和校验规则2.1查看系统默认字符集以及校验规则2.2查看数据库支持的字符集2.3查看数据库支持的字符集校验规则2.4校验规则对数据库的影响 3.操纵数据库3.1查看数据库3.2显示创建语句3.3修改数据库3.4数据库删除3.5备…

DevOps搭建(五)-JDK安装详细步骤

1、官网下载 官方网站下载JDK&#xff0c;这里我们安装JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html 点击上图中的Java SE Downloads项目&#xff0c;也可直接点击下面链接进入&#xff1a; Java Downloads | Oracle 往下滚…

Android14创建Pixel6 Pro模拟器(一百七十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

C++设计模式-Builder 构建器

通过“对象创建” 模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持对象创建的稳定。它是接口抽象之后的第一步工作。 一、动机 在软件系统中&#xff0c;有时候面临着“一个复…

STM32--Wi-Fi插座_风扇_灯

项目需求 两个互相通信的双方&#xff0c;波特率必须相同!!!!!! 通过 ESP8266 模块&#xff0c;实现手机控制 wifi 插座 / 风扇 / 灯。 项目设计 串口 1 用于与 ESP8266 通讯&#xff0c;串口 2 连接 PC &#xff0c;用于打印 log &#xff0c;查看系统状态。 项目实现 注意&a…

网络安全项目实战(四)--报文检测

8. TCP/UDP 段 目标 了解 TCP 段头的组织结构了解 UDP 段头的组织结构掌握 TCP/UDP 段的解析方式 8.1. UDP 段格式 下图是UDP的段格式&#xff08;该图出自[TCPIP]&#xff09;。 8.2. UDP头部 //UDP头部&#xff0c;总长度8字节// /usr/include/linux/udp.h struct udphdr …

拦截器实现指定的IP白名单进行访问规定的Controller

需求&#xff1a;只允许内网的IP&#xff08;也就是IP白名单&#xff09;进行访问VideoController和ImgController&#xff0c;其余的FontController可以随便访问不做限制 总体的项目结构&#xff1a; 1、先写好业务代码三个Controller 访问的路径分别是&#xff1a; /api/…

【三视图】咒语 生成人物

revAnimated_v122.safetensors 杰作&#xff0c;最佳质量&#xff0c;角色设计&#xff0c;三视图&#xff0c;前视图&#xff0c;侧视图&#xff0c;后视觉&#xff0c;呆萌&#xff0c;可爱&#xff0c;简单的背景&#xff0c; (badhandv4:1.4),ng_deepnegative_v1_75t,negat…

qt-C++笔记之模拟实现一个linux终端窗口

qt-C笔记之模拟实现一个linux终端窗口 code review! 文章目录 qt-C笔记之模拟实现一个linux终端窗口一.运行二.main.cpp三.不足&#xff0c;待改进点 一.运行 二.main.cpp 代码 #include <QApplication> #include <QPlainTextEdit> #include <QLineEdit>…

新版Spring Security6.2 - Digest Authentication

前言&#xff1a; 书接上文&#xff0c;上次翻译basic的这页&#xff0c;这次翻译Digest Authentication这页。 摘要认证-Digest Authentication 官网的警告提示&#xff1a;不应在应用程序中使用摘要式身份验证&#xff0c;因为它不被认为是安全的。最明显的问题是您必须以…

聊聊Java中的异常

什么是异常 关于Java的异常&#xff0c;我们认为符合大致分为以下几种情况: 程序逻辑运行结果不符合预期。程序执行时抛出各种exception。因为各种原因导致服务崩溃。 Java异常类体系结构如下图所示: Exception和Error的区别 Exception Exception或者Exception自类的异常对…

有关爬虫http/https的请求与响应

简介 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;&#xff1a;是一种发布和接收 HTML页面的方法。 HTTPS&#xff08;Hypertext Transfer Protocol over Secure Socket Layer&#xff09;简单讲是HTTP的安全版&#xff0c;在HTT…

【亲测】获取百度智能云access_token并存储,百度智能云access_token有效期

百度智能云服务内置很多api接口&#xff08;文字识别&#xff0c;企业信息识别&#xff0c;等&#xff09;&#xff0c;所有百度智能云自带的接口都会用到百度的access_token 第一步&#xff1a;登录百度智能云管理中心 第二步&#xff1a;创建账户&#xff0c;完整身份认证 …

Binder IPC通讯流程 摘要

一次完整的 Binder IPC 通信过程通常是这样&#xff1a; 首先 Binder 驱动在内核空间创建一个数据接收缓存区&#xff1b;接着在内核空间开辟一块内核缓存区&#xff0c;建立内核缓存区和内核中数据接收缓存区之间的映射关系&#xff0c;以及内核中数据接收缓存区和接收进程用…

Leetcode2048. 下一个更大的数值平衡数

Every day a Leetcode 题目来源&#xff1a;2048. 下一个更大的数值平衡数 解法1&#xff1a;枚举 这种题不能想复杂了&#xff0c;枚举大法好。 代码&#xff1a; /** lc appleetcode.cn id2048 langcpp** [2048] 下一个更大的数值平衡数*/// lc codestart class Soluti…