linux服务-RabbitMQ 原理与安装

RabbitMQ 原理与安装

参考:RabbitMQ 对 Erlang 版本要求erlang下载页, rabbitmq下载页延时队列插件-rabbitmq-delayed

RabbitMQ 是基于 AMQP(高级消息队列协议) 实现的开源消息中间件,由 Erlang 语言开发,核心优势是高可用、可扩展、支持多种消息模式,广泛用于系统解耦、异步通信、流量削峰等场景。

一、原理

  • 角色与架构

    RabbitMQ 的核心架构包含以下组件,通过 生产者 - 消费者 模型实现消息的可靠传递:

    组件 作用
    生产者(Producer) 发送消息的应用程序,将消息投递到 Exchange。
    消费者(Consumer) 接收消息的应用程序,从 Queue 中获取并处理消息。
    交换机(Exchange) 接收生产者的消息,根据绑定规则(Binding)将消息路由到对应的 Queue。
    队列(Queue) 存储消息的容器,消息最终落地到 Queue,供消费者消费。
    绑定(Binding) 连接 Exchange 和 Queue 的规则,包含路由键(Routing Key)匹配逻辑。
    虚拟主机(VHost) 逻辑隔离的独立环境,可理解为 "命名空间",不同 VHost 互不干扰,支持权限隔离。
    连接(Connection) 生产者 / 消费者与 RabbitMQ 服务器的 TCP 连接(长连接)。
    信道(Channel) 建立在 Connection 之上的轻量级连接,避免频繁创建 TCP 连接,节省资源。
  • 工作流程

    1. 生产者通过 Channel 向 RabbitMQ 服务器发送消息,指定目标 Exchange 和 Routing Key;

    2. Exchange 根据自身类型和 Binding 规则,将消息路由到一个或多个 Queue;

    3. 消费者通过 Channel 监听指定的 Queue,获取并处理消息;

    4. 消息处理完成后,消费者向 RabbitMQ 发送 ACK(确认),RabbitMQ 才会删除该消息(可配置自动 / 手动 ACK)。

  • 交换机(Exchange)类型

    Exchange 是路由消息的核心,不同类型对应不同的路由规则:

    类型 路由规则 典型场景
    Direct 消息的 Routing Key 与 Binding 的 Routing Key 完全匹配,才路由到对应 Queue 一对一消息(精准路由)
    Fanout 忽略 Routing Key,将消息广播到所有绑定的 Queue 广播 / 订阅(如日志推送)
    Topic 支持通配符匹配(* 匹配一个单词,# 匹配多个单词),模糊路由 多对多消息(如按主题分类)
    Headers 不依赖 Routing Key,通过消息头(Headers)键值对匹配 复杂属性匹配(较少用)
  • 核心特性

    • 消息确认机制:生产者确认(Publisher Confirm)确保消息到达 Exchange;消费者 ACK 确保消息被正确处理;
    • 持久化:Queue、Exchange、消息均可配置持久化,避免服务器宕机丢失;
    • 死信队列(DLX):处理失败 / 过期的消息,支持消息重试或归档;
    • 延迟队列:通过死信队列 + TTL(消息过期时间)实现延迟消息;
    • 集群与镜像队列:支持多节点集群,镜像队列保障 Queue 高可用;
    • 限流:消费者可限制单次获取的消息数量,避免过载。

二、单机安装

  • 前置说明

    • RabbitMQ 依赖 Erlang 语言环境,需先安装 Erlang,再安装 RabbitMQ。
    • 服务器已配置网络,关闭 / 放行防火墙(或开放 5672(AMQP)、15672(管理界面)端口);
    • 系统版本:CentOS 7/8、Ubuntu 20.04+ 均可,以下以 CentOS 7 为例。
  • 安装Erlang

    • 通过 YUM 源安装

      bash 复制代码
      # 1. 添加 Erlang 官方 YUM 源
      vim /etc/yum.repos.d/rabbitmq-erlang.repo
      # 写入以下内容(以 Erlang 25.3 为例)
      [rabbitmq-erlang]
      name=rabbitmq-erlang
      baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
      repo_gpgcheck=1
      gpgcheck=1
      enabled=1
      gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
             https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
      sslverify=1
      sslcacert=/etc/pki/tls/certs/ca-bundle.crt
      
      # 2. 安装 Erlang
      yum install -y erlang
      
      # 3. 验证 Erlang 安装
      erl -v  # 输出 Erlang 版本即成功
    • 源码安装 <-- 推荐 扩展性更强

      bash 复制代码
      用web界面下载: https://www.erlang.org/patches/otp-26.2.5.16
      
      yum -y install gcc gcc-c++ ncurses-devel wxGTK wxGTK-devel gtk2-devel libGLU-devel openssl openssl-devel
      cd /opt/
      tar xf otp_src_26.2.5.16.tar.gz 
      cd /opt/otp_src_26.2.5.16
        ./configure --prefix=/opt/mq/erlang
        make -j 4 && make -j 4 install
        
      # 验证版本
      /opt/mq/erlang/bin/erl
          Erlang/OTP 26 [erts-14.2.5.12] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
  • 安装 RabbitMQ

    • yum安装

      bash 复制代码
      # 1. 添加 RabbitMQ YUM 源
      vim /etc/yum.repos.d/rabbitmq.repo
      # 写入以下内容(以 RabbitMQ 3.12.x 为例)
      [rabbitmq_server]
      name=rabbitmq_server
      baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/$basearch
      repo_gpgcheck=1
      gpgcheck=1
      enabled=1
      gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
             https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
      sslverify=1
      sslcacert=/etc/pki/tls/certs/ca-bundle.crt
      
      # 2. 安装 RabbitMQ 服务器
      yum install -y rabbitmq-server
      
      # 3. 验证安装
      rabbitmq-server -v  # 输出 RabbitMQ 版本即成功
    • 源码安装

      bash 复制代码
      # 下载包
      wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz
      
      # 解压并配置
      tar xf rabbitmq-server-generic-unix-3.13.7.tar.xz -C /opt/mq/
      cd /opt/mq/
      mv rabbitmq_server-3.13.7/ rabbitmq
      chmod 777 rabbitmq/ -R
      cd rabbitmq
      mkdir license
      mv LICENSE* license    <-- 把源码包里的LICENSE文件都挪走 
      
      # 创建数据/日志目录并授权
      mkdir -p /opt/mq/rabbitmq/{mnesia,log}
      chmod -R 755 /opt/mq/rabbitmq/{mnesia,log}
      • 配置自启脚本

        bash 复制代码
        cat > /etc/systemd/system/rabbitmq-server.service << EOF
        [Unit]
        Description=RabbitMQ Server
        Documentation=man:rabbitmq-server(8)
        After=network.target
        Wants=network.target
        
        [Service]
        User=root
        Group=root
        
        Environment="PATH=/opt/mq/erlang/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        Environment="RABBITMQ_HOME=/opt/mq/rabbitmq"
        Environment="RABBITMQ_MNESIA_BASE=/opt/mq/rabbitmq/mnesia"
        Environment="RABBITMQ_LOG_BASE=/opt/mq/rabbitmq/log"
        ExecStart=/opt/mq/rabbitmq/sbin/rabbitmq-server
        ExecStop=/opt/mq/rabbitmq/sbin/rabbitmqctl stop
        ExecStop=/bin/sh -c 'PID=$(rabbitmqctl status 2>/dev/null | grep "pid" | awk "{print \$2}" | tr -d ","); [ -n "$PID" ] && kill -9 $PID'
        ExecReload=/opt/mq/rabbitmq/sbin/rabbitmqctl stop && /opt/mq/rabbitmq/sbin/rabbitmq-server
        
        Restart=on-failure
        RestartSec=5
        TimeoutStartSec=60
        TimeoutStopSec=60
        LimitNOFILE=65535  # 提高文件描述符限制(生产环境必备)
        LimitNPROC=65535
        PrivateTmp=true
        
        [Install]
        WantedBy=multi-user.target
        
        EOF
      • 启动服务

        bash 复制代码
        # 启动 RabbitMQ
        systemctl start rabbitmq-server
        
        # 设置开机自启
        systemctl enable rabbitmq-server
        
        # 查看状态(active (running) 即为正常)
        systemctl status rabbitmq-server

2.1、启用管理插件

  • RabbitMQ 默认无 Web 界面,需手动启用插件:

    bash 复制代码
    # 配置环境变量
    echo "RABBITMQ_HOME=/opt/mq/erlang" >> /etc/profile
    echo "export PATH=\$RABBITMQ_HOME/bin:\$PATH" >> /etc/profile
    source  /etc/profile
    
    cd /opt/mq/rabbitmq/sbin
    # 启用管理插件
    [root@localhost sbin]# ./rabbitmq-plugins enable rabbitmq_management
    .....
    Applying plugin configuration to rabbit@localhost...
    The following plugins have been enabled:
      rabbitmq_management
      rabbitmq_management_agent
      rabbitmq_web_dispatch
    started 3 plugins.
    
    # 重启服务(可选)
    systemctl restart rabbitmq-server
  • 添加用户

    bash 复制代码
    cd /opt/mq/rabbitmq/sbin
    
    # 1. 添加管理员用户(替换 username/password 为自定义)
    ./rabbitmqctl add_user admin 123456
    
    # 2. 设置用户为管理员角色
    ./rabbitmqctl set_user_tags admin administrator
    
    # 3. 设置用户权限(允许访问所有 VHost,读写所有资源)
    ./rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
    
    # 4. 可选:删除默认 guest 用户(提高安全性)
    ./rabbitmqctl delete_user guest
    
    # 5. 查看用户列表
    ./rabbitmqctl list_users
  • 开放端口(防火墙)- 如开

    bash 复制代码
    # 开放 AMQP 端口(5672)和 Web 管理端口(15672)
    firewall-cmd --add-port=5672/tcp --permanent
    firewall-cmd --add-port=15672/tcp --permanent
    
    # 重启防火墙
    firewall-cmd --reload
  • 访问 Web 管理界面

    打开浏览器,访问 http://服务器IP:15672,输入上述创建的用户名(如 admin)和密码(如 123456),即可进入 RabbitMQ 管理控制台:

    • 可查看 Queue、Exchange、用户、连接等信息;
    • 可手动创建 Queue/Exchange、绑定规则、发送测试消息等。

三、集群安装

RabbitMQ 集群核心是 Erlang 分布式节点通信 + 队列镜像 / 分片 ,实现高可用和负载均衡。以下以 3 节点集群 为例(CentOS 7/8,自定义路径 /opt/mq/rabbitmq/opt/mq/erlang),覆盖集群搭建、镜像队列配置、故障切换全流程。

  • 前置说明

    • 基础环境准备

      节点 IP 主机名(建议) 核心路径
      节点 1(主) 192.168.189.128 rabbitmq-node1 /opt/mq/rabbitmq、/opt/mq/erlang
      节点 2 192.168.189.129 rabbitmq-node2 同上
      节点 3 192.168.189.135 rabbitmq-node3 同上
    • 统一主机名与 hosts 解析

      bash 复制代码
      # 1. 设置主机名(每个节点对应自己的主机名)
      # 节点1:
      hostnamectl set-hostname rabbitmq-node1
      # 节点2:
      hostnamectl set-hostname rabbitmq-node2
      # 节点3:
      hostnamectl set-hostname rabbitmq-node3
      
      # 2. 修改 /etc/hosts,添加所有节点解析
      cat >> /etc/hosts << EOF
      192.168.1.10 rabbitmq-node1
      192.168.1.11 rabbitmq-node2
      192.168.1.12 rabbitmq-node3
      EOF
      
      # 3. 验证解析
      ping rabbitmq-node2 -c 2  # 节点1 ping 节点2,能通即正常
    • 端口说明

      端口号 核心角色 通信对象 开放范围建议 关键作用概括
      4369 Erlang 节点发现 集群内所有节点互访 仅集群内网 节点发现,Erlang 分布式基础
      25672 集群内部通信 集群内所有节点互访 仅集群内网 同步元数据、镜像队列数据复制
      5672 客户端业务通信 生产者 / 消费者 ↔ 集群 仅业务网段 AMQP 协议端口,承载消息收发
      15672 Web 管理界面 运维端 ↔ 集群 仅运维网段 可视化管理、监控集群状态
      • 依赖逻辑: 4369(节点发现)→ 25672(集群通信)→ 5672(业务交互)→ 15672(运维管理)

        • 无 4369:集群节点无法发现彼此,集群搭建失败;
        • 无 25672:节点可发现但无法同步数据,集群退化为独立节点;
        • 无 5672:客户端无法收发消息,业务中断;
        • 无 15672:仅影响可视化管理,不影响集群核心功能。
      • 防火墙配置

        bash 复制代码
        # 临时关闭防火墙(测试环境)
        systemctl stop firewalld && systemctl disable firewalld
        
        # 生产环境开放端口(替代关闭防火墙)
        firewall-cmd --add-port=4369/tcp --permanent
        firewall-cmd --add-port=25672/tcp --permanent
        firewall-cmd --add-port=5672/tcp --permanent
        firewall-cmd --add-port=15672/tcp --permanent
        firewall-cmd --reload
        
        # 富策略
        firewall-cmd --add-rich-rule='rule family="ipv4" source address="地址/32" port port="端口" protocol="tcp" accept' --permanent
        firewall-cmd --reload
    • 统一 Erlang Cookie

      RabbitMQ 集群通过 Erlang Cookie 认证节点,所有节点必须使用相同的 Cookie 文件:

      bash 复制代码
      # 1. 先停止所有节点的 RabbitMQ 服务
      systemctl stop rabbitmq-server
      
      # 2. 从节点1复制 Cookie 到其他节点(推荐以节点1为基准)
      # 节点1 执行(查看 Cookie 路径,默认在 /root/.erlang.cookie):
      cat /root/.erlang.cookie
      
      # 从节点1 scp 到 节点2、3
      scp /root/.erlang.cookie root@rabbitmq-node2:/root/
      scp /root/.erlang.cookie root@rabbitmq-node3:/root/
      
      # 3. 统一 Cookie 权限(所有节点)
      chmod 400 /root/.erlang.cookie  # 必须 400 权限,否则认证失败
  • 从节点1将 erlang、rabbitmq 压缩直接scp到 节点2、3

    • 节点2、3 跟单机一样都配一遍

3.1、初始化集群

  • 启动所有节点的 RabbitMQ 服务

    bash 复制代码
    # 启动服务
    systemctl start rabbitmq-server
    
    # 验证启动状态
    systemctl status rabbitmq-server  # 确保 active (running)
  • 将节点 2、3 加入节点 1 的集群

    bash 复制代码
    # 1. 停止节点 2.3 的 RabbitMQ 应用(保留 Erlang 节点运行)
    /opt/mq/rabbitmq/sbin/rabbitmqctl stop_app
    
    # 2. 重置节点(清空本地数据,避免冲突)
    /opt/mq/rabbitmq/sbin/rabbitmqctl reset
    
    # 3. 加入节点 1 的集群(指定节点 1 的 Erlang 节点名,格式:rabbit@主机名)
    /opt/mq/rabbitmq/sbin/rabbitmqctl join_cluster rabbit@rabbitmq-node1
    
    # 4. 重启 RabbitMQ 应用
    /opt/mq/rabbitmq/sbin/rabbitmqctl start_app
    
    # 5. 验证集群状态
    /opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status
    
    Running Nodes
    
    rabbit@rabbitmq-node1
    rabbit@rabbitmq-node2
    rabbit@rabbitmq-node3

3.2、配置镜像队列

默认集群中,Queue 仅存储在创建它的节点上,若该节点宕机,Queue 不可用。镜像队列 会将 Queue 复制到集群多个节点,实现故障自动切换。

  • 设置镜像队列策略(所有节点生效)

    bash 复制代码
    # 在任意节点执行(推荐节点1)
    /opt/mq/rabbitmq/sbin/rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
    
    # 参数说明:
    # ha-all:策略名称(自定义)
    # "^":匹配所有队列(正则,也可指定特定队列,如 "^order.*" 匹配以 order 开头的队列)
    # ha-mode":"all":将队列镜像到集群所有节点(可选 "exactly" 配置固定数量,如 "ha-params":2 镜像到2个节点)
    # ha-sync-mode":"automatic":自动同步队列数据(默认手动,需手动执行 sync_queue)
    
    # 返回值 Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "/" ...
  • 验证镜像队列策略

    bash 复制代码
    [root@localhost mq]# /opt/mq/rabbitmq/sbin/rabbitmqctl list_policies
    
    Listing policies for vhost "/" ...
    vhost	name	pattern	apply-to	definition								priority
    /		ha-all	^		all		{"ha-mode":"all","ha-sync-mode":"automatic"}	0

3.3、集群管理与常用操作

  • 查看集群状态

    bash 复制代码
    /opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status
    # 关键输出:
    # - nodes.disc:磁盘节点列表(所有节点默认是磁盘节点)
    # - running_nodes:运行中的节点
    # - partitions:网络分区(空则正常)
    
    Maintenance status
    Node: rabbit@rabbitmq-node1, status: not under maintenance
    关键信息 含义与影响
    状态值:not under maintenance 节点正常对外提供服务,可接收客户端连接(生产者 / 消费者)、参与集群通信(元数据同步、镜像队列复制),无功能限制。
    适用场景 集群日常运行状态,所有节点均在线且正常工作,无需人工干预。
  • 移除集群节点(如移除节点 3)

    bash 复制代码
    # 1. 节点3 执行:停止应用并重置
    /opt/mq/rabbitmq/sbin/rabbitmqctl stop_app
    /opt/mq/rabbitmq/sbin/rabbitmqctl reset
    
    # 2. 节点1 执行:移除节点3
    /opt/mq/rabbitmq/sbin/rabbitmqctl forget_cluster_node rabbit@rabbitmq-node3
    
    # 3. 节点3 执行:重启应用(退出集群后独立运行)
    /opt/mq/rabbitmq/sbin/rabbitmqctl start_app
  • 故障切换测试

    bash 复制代码
    # 1. 停止节点1的 RabbitMQ 服务(模拟宕机)
    systemctl stop rabbitmq-server
    
    # 2. 节点2 查看集群状态(应显示节点1停止,节点2/3运行)
    /opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status
    
    # 3. 验证队列可用性:生产者/消费者连接节点2,仍可正常收发消息
    # 4. 重启节点1(自动重新加入集群)
    systemctl start rabbitmq-server
  • 集群用户同步

    RabbitMQ 集群会自动同步用户、权限、VHost 配置,只需在一个节点创建用户,所有节点生效

    bash 复制代码
    # 在节点1创建管理员用户(所有节点可共用)
    /opt/mq/rabbitmq/sbin/rabbitmqctl add_user admin 123456
    /opt/mq/rabbitmq/sbin/rabbitmqctl set_user_tags admin administrator
    /opt/mq/rabbitmq/sbin/rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

3.4、启用管理插件

访问任意节点的管理界面(http://节点IP:15672),登录 admin 用户:

  • 顶部导航栏 AdminNodes:查看所有节点状态(运行 / 停止);

  • Queues 页面:队列旁会显示 Mirrored to [2] nodes(镜像到 2 个节点),表示镜像队列生效;

  • AdminPolicies:查看已配置的镜像队列策略。


四、注意事项

  • 注意事项

    • 磁盘节点 vs 内存节点

      • 默认所有节点是 磁盘节点(存储集群元数据、队列数据),生产环境建议至少 2 个磁盘节点(避免单点故障);
      • 内存节点(仅存储内存,速度快):加入集群时指定 --ram,如 rabbitmqctl join_cluster --ram rabbit@rabbitmq-node1,适合高并发读场景。
    • 网络分区处理

      集群节点网络中断会导致 网络分区,需配置自动恢复:

      bash 复制代码
      # 所有节点修改 RabbitMQ 配置文件(/etc/rabbitmq/rabbitmq.conf)
      echo "cluster_partition_handling = autoheal" >> /etc/rabbitmq/rabbitmq.conf
      
      # 重启所有节点
      systemctl restart rabbitmq-server
    • Erlang 版本兼容

      所有节点必须使用 相同版本的 Erlang 和 RabbitMQ,否则集群无法通信。

  • 常见故障排查

    1. 节点加入集群失败

      • 检查 /.erlang.cookie 文件是否一致、权限是否为 400;
      • 检查 hosts 解析是否正确,节点间 4369/25672 端口是否通;
      • 执行 rabbitmqctl status 查看节点状态,确保 Erlang 节点正常运行。
    2. 镜像队列不生效

      • 检查策略是否匹配队列名称(正则是否正确);

      • 新建队列才会应用策略,已有队列需重新创建或手动同步:

        bash 复制代码
        rabbitmqctl sync_queue 队列名
    3. 节点宕机后队列不可用

      • 确认镜像队列策略已配置(ha-mode:all);
      • 检查节点宕机后,其他节点是否在 running_nodes 列表中。
  • 生产环境优化建议

    • 节点数量:建议 3/5 个节点(奇数,避免脑裂);
    • 存储:队列数据目录挂载独立磁盘,开启持久化;
    • 监控:通过 Prometheus + Grafana 监控集群节点状态、队列长度、消息速率;
    • 限流 :配置消费者限流(basic.qos),避免单节点过载;
    • 备份 :定期执行 rabbitmqctl export_definitions 备份集群配置。
相关推荐
HLC++12 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室13 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy16 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕17 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫18 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生18 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1119 小时前
linux基础IO
linux·运维·服务器
BelongPanda21 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯21 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_777998341 天前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器