RabbitMQ
pg addon install rabbitmq 以托管容器方式运行 RabbitMQ 4.4.0,直接使用官方
docker.io/library/rabbitmq 的 -management 镜像(内含 Web UI 与 HTTP API)。和
Kafka、ClickHouse 一样,RabbitMQ 是顶层插件:pgcli 负责渲染 rabbitmq.conf、管理
管理员账号、绑定挂载数据目录,并以 host 网络启动容器。
插件支持单节点,或作为多机集群的一个成员。集群使用 etcd 自动发现
(rabbitmq_peer_discovery_etcd):每台主机以相同的 --cluster 名和 etcd endpoint 列表安装
一个成员,首次启动时成员自动注册并互相发现——不需要静态 peer 列表,也不需要手动
join_cluster。不配置 federation、shovel、MQTT 或 STOMP;vhost、用户、权限、策略、
exchange 等高级管理通过 management UI 或 pg addon rabbitmq shell 里的 rabbitmqctl
完成。常用队列操作已封装为 pg addon rabbitmq queue 子命令(见队列与消息)。
集群模式下 declare 默认创建 quorum 队列(见集群)。
认证始终开启。 AMQP 与 management UI 都需要 pgcli 创建的管理员账号(默认
admin,20 位自动生成密码)。--listen默认127.0.0.1。对外暴露时,密码就是安全 边界:TLS 只加密传输,不认证客户端(verify_none、fail_if_no_peer_cert = false)。
参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--name |
rabbitmq |
实例名(map key,也是子命令默认名字) |
--version |
4.4.0 |
上游镜像 tag,实际拉取 docker.io/library/rabbitmq:<version>-management |
--admin-user |
admin |
管理员账号,首启创建,每次启动对账 |
--admin-password |
自动生成(20 位) | 管理员密码;同时存入 pg.yaml 与 0600 secret 文件。集群模式拒绝明文,请用 --secrets-from-etcd 或 --admin-password-file |
--admin-password-file FILE |
— | 从 FILE 读取管理员密码(单行)。集群成员首次安装必填(使用 --secrets-from-etcd 时除外);单机实例也可使用 |
--data-dir |
<base_dir>/addon/rabbitmq/<name>/data |
数据目录,挂载到 /var/lib/rabbitmq;必须是绝对路径 |
--listen |
单机 127.0.0.1,集群 0.0.0.0 |
AMQP、AMQPS(启用 --tls 时)与 management 监听共用的绑定地址。0.0.0.0 会暴露所有已启用监听;集群模式不能是 loopback |
--cluster NAME |
— | 加入/创建名为 NAME 的 RabbitMQ 集群。空 = 单机;所有成员必须相同 |
--node-name NODE@HOST |
— | 本成员的 Erlang 节点名(如 rabbit@192.0.2.11)。集群成员首次安装必填;必须唯一。host 为 IP 时无需名称解析;为主机名时必须在每个成员上可解析 |
--etcd m1,m2 |
— | 用本地 etcd addon 成员作为发现 endpoint;与 --etcd-endpoints 二选一(后者优先) |
--etcd-endpoints host:port,... |
— | 外部 etcd 发现 endpoint;可重复或逗号分隔。仅支持明文 HTTP,可带 http:// 前缀(会被去掉) |
--erlang-cookie-file FILE |
— | 从 FILE 读取共享的 Erlang cookie。集群成员首次安装必填(使用 --secrets-from-etcd 时除外);值保存后不可变 |
--secrets-from-etcd |
false | 从 pg addon rabbitmq secret generate 写入的 etcd key 读取两个共享密钥(推荐,无需在主机间复制文件)。不能与 --erlang-cookie-file 或 --admin-password-file 同时使用 |
--amqp-port |
自动(基准 5672) |
明文 AMQP 端口;0 = 从 rabbitmq_start_port 自动分配 |
--management-port |
自动(基准 15672) |
Management HTTP UI/API 端口;0 = 从 rabbitmq_management_start_port 自动分配 |
--tls |
false | 在明文监听之外增加 AMQPS 与 management HTTPS,使用 pgcli 自签 CA 签发的证书 |
--tls-cert FILE |
— | 自带服务端证书(PEM 链);必须与 --tls-key 同时传入;隐含 --tls;--listen 不是 0.0.0.0 时必须覆盖该地址 |
--tls-key FILE |
— | 自带私钥(PKCS#8/PKCS#1/SEC1),与 --tls-cert 配对 |
--tls-port |
自动(基准 5671) |
AMQPS 端口;0 = 从 rabbitmq_tls_start_port 自动分配;需要 --tls |
--config-option K=V |
— | 额外的 rabbitmq.conf 配置(heartbeat=60、log.file.level=debug);可重复;替换已存储的覆盖表 |
--force |
false | 重新渲染配置并重建容器;保留数据与已存储的密码。集群模式下 --cluster、--node-name 与 Erlang cookie 不可变,--etcd-endpoints 可以更新 |
RabbitMQ 不使用 --image,用 --version。--version 接受任意合法的上游 tag,但 tag 必须
真实存在,否则 pull 失败;镜像引用始终是 docker.io/library/rabbitmq:<version>-management。
安装
⚠️ 单机版创建的是持久化 classic 队列,但消息默认不持久化。classic 的消息持久化是
逐条消息的属性,必须由发布端在每次 publish 时设置(pg addon rabbitmq queue publish
加 --property delivery_mode=2,应用客户端设置 delivery_mode=2),不存在队列参数或
policy 级别的开关。未设置时 broker 重启后队列仍在、消息丢失。集群模式使用 quorum 队列,
会自动持久化所有消息。
第二个实例会从各自的端口池取下一个空闲端口(例如 AMQP 5673、management 15673、
EPMD 4370、distribution 25673):
不带 --force 重复 install 是幂等的,只打印当前状态。带 --force 时,pgcli 会重写
rabbitmq.conf、重写 enabled_plugins、重建容器并重新对账管理员账号;数据目录与密码保留。
密码只在安装时打印一次,之后可随时取回:
Management UI 与 API
Management Web UI 的地址:
执行 pg addon rabbitmq status --name rmq 可打印本实例准确的 Management: 地址(随
--listen 与 --management-port 变化)。浏览器打开该地址,用管理员账号登录,密码通过
pg addon password rabbitmq --name rmq 获取。集群模式下任意成员都提供相同的 UI,
Overview → Nodes 可看到整个集群。
同一端口也提供 HTTP API:
CLI 未封装的能力——vhost、用户、权限、策略与 exchange 定义——都通过 UI 完成。
常用队列操作已提供 pg addon rabbitmq queue ... 命令(见队列与消息)。
端口
| 端点 | 默认 | 端口池 |
|---|---|---|
| AMQP(明文) | 5672 |
rabbitmq_start_port,默认 5672 |
| AMQPS(TLS) | 5671(启用 --tls 时) |
rabbitmq_tls_start_port,默认 5671 |
| Management HTTP UI/API | 15672 |
rabbitmq_management_start_port,默认 15672 |
| Management HTTPS | 15671(启用 --tls 时) |
rabbitmq_management_tls_start_port,默认 15671 |
| Erlang EPMD | 4369 |
rabbitmq_epmd_start_port,默认 4369 |
| Erlang distribution | 25672 |
rabbitmq_dist_start_port,默认 25672 |
每个池独立分配:实例按名字排序,显式端口不会被覆盖,宿主已监听的端口会被跳过。所有 RabbitMQ 实例的端口必须互不重复。
EPMD 与 distribution 是基础设施端口,不是客户端端点。单机实例以
RABBITMQ_NODENAME=rabbit@localhost、ERL_EPMD_ADDRESS=127.0.0.1 和独立的
EPMD/distribution 端口运行,rabbitmq.conf 里固定
distribution.listener.interface = 127.0.0.1——Erlang distribution 永不对外暴露,多个单机
实例可在同一宿主共存,也不会与宿主的 Erlang 安装冲突。
集群成员不同:每个成员固定使用 EPMD 4369 与 distribution 25672,distribution 监听
--listen(默认 0.0.0.0)。因此一台主机最多运行一个集群 RabbitMQ 实例,且 4369、
25672 必须能被其他成员访问(见集群)。
不启用 rabbitmq_prometheus 插件。 pgcli 挂载自己的 enabled_plugins(单机只有
rabbitmq_management,集群模式为 rabbitmq_management 与 rabbitmq_peer_discovery_etcd),
保证每个实例行为一致,也不会多开一个无认证的固定 metrics 监听。
集群
集群通过 etcd 自动发现组建,不使用静态 peer 列表。每台主机以相同的 --cluster 名和
etcd endpoint 列表运行一个成员;首次启动时成员在 etcd 中注册自己,并加入已经注册的节点。
前置条件:
- etcd 3.4+,每个成员都能以明文 HTTP 访问。测试时单成员 etcd 即可,但生产环境的发现
存储本身应当冗余。本版本 pgcli 不支持该 etcd 连接的 TLS 或认证,请放在可信网络中。可以
用 pgcli 的 etcd addon(
pg addon install etcd ...),也可以用--etcd-endpoints指向 外部 etcd。 - 节点名唯一。
--node-name rabbit@host在集群内必须唯一。host 部分可以是主机名或 IPv4;拒绝 loopback 与 IPv6。使用 IP 时成员直接互连,完全不需要名称解析——没有内网 DNS 时推荐这种方式。使用主机名时,每个成员都必须能解析它(DNS 或/etc/hosts): etcd 发现只注册rabbit@host,不提供地址。FQDN、IP 会让 RabbitMQ 自动使用 Erlang long names。 - 共享密钥。 所有成员必须使用相同的 Erlang cookie 和相同的管理员密码。先在管理机
执行一次
pg addon rabbitmq secret generate:它生成本地0600文件并把内容写入 etcd; 各成员安装时用--secrets-from-etcd读取,无需在主机间复制文件。pgcli 会把两个值保存到pg.yaml和0600secret 文件,因此start与 autostart 不再依赖 etcd 或原始文件。 仍支持手动分发文件时使用--erlang-cookie-file/--admin-password-file。这两个都是 集群级密钥,AMQP 客户端都不需要。 - 版本一致。 每个成员的
--version相同。 - 集群名一致。 不同的
--cluster会在同一个 etcd 中形成另一套集群;pgcli 通过cluster_formation.etcd.cluster_name隔离。
在管理机上生成并发布一次共享密钥:
命令不会打印密钥值。它会写入 /tmp/rmq.cookie 与 /tmp/rmq.admin(权限 0600),并把
相同内容写入以下 etcd key(不是文件):
这两个本地文件各有明确用途:
| 文件 | 用途 |
|---|---|
/tmp/rmq.cookie |
共享 Erlang cookie。仅用于集群成员之间的 Erlang distribution 握手(EPMD 4369、distribution 25672),AMQP 与管理客户端从不使用。 |
/tmp/rmq.admin |
共享的broker 管理员密码,用于创建/对账 admin 账号。它是安装输入,不是客户端凭据文件:应用应使用自己创建的 RabbitMQ 用户连接。需要以管理员身份登录时,用 pg addon password rabbitmq --name mq 取回已保存的密码即可,不必保留该文件。 |
这两个文件都是安装引导/分发用的中间产物。安装时每个成员都会把值保存到 pg.yaml 和
自己的 0600 secret 文件,start/autostart 不会读取 /tmp 下的文件,因此所有成员安装
完成后即可删除。若不用 --secrets-from-etcd 而选择手动分发,则把这两个文件复制到各主机
(内容必须一致),并通过 --erlang-cookie-file / --admin-password-file 传入;各主机的
路径可以不同。成员安装完成后绝不要重新生成 Erlang cookie——它不可变,cookie 不一致的
节点无法加入集群。
在各成员主机上安装(只有 --node-name 不同;用各主机 IP 可免去 /etc/hosts/DNS):
每个成员都读取相同的值,不需要手动复制文件。若倾向手动分发,可跳过 secret generate,
改用两个 --*-file 参数。
etcd 中这些值是明文的。任何能访问 etcd client 端口的人都能读到集群凭据,因此请把
2379 限制在成员主机与管理机之间;不要把密钥放进其他租户可读的共享 etcd。
第一个成员会启动一个只有自己的集群并打印提示;后续成员通过 etcd 发现并自动加入。发现只在 Mnesia 为空时执行——已加入的成员重启时联系 last-seen peers。
发现 key 位于
因此只要 --cluster 名不同,多套集群可以共用一个 etcd。
队列语义
- 集群模式下
pg addon rabbitmq queue declare默认--type quorum。Quorum 队列会在所有成员 上复制(默认 quorum size 为 3,以成员数为上限),是 RabbitMQ 4.x 唯一支持复制的队列类型。 --type classic仍可使用,但 classic 队列不复制:它只存在于声明它的节点上,该节点 宕机时队列不可用。仅建议用于非关键或可重建的数据。--durable=false、quorum +--auto-delete等限制不变(见队列与消息)。- 每个节点都能服务客户端,management API 也会展示整个集群,因此客户端可以连接任意成员。 生产环境请配置多个 endpoint,或前置 TCP 负载均衡。
查看与下线成员
cluster status 输出 rabbitmqctl cluster_status,包含所有 running nodes。cluster forget
用于把已停止、永久下线的成员从集群元数据中移除;它拒绝 forget 本机节点。移除成员后,
重新平衡 quorum 队列的副本分布:
只是临时停机的成员不需要任何操作:重启后会通过 last-seen peers 自动重新加入。不要在节点
仍计划恢复时执行 cluster forget——旧节点将无法重新加入,只能清空数据重建(或在对端 forget
后用空数据目录重新添加)。
集群约束
--cluster、--node-name与 Erlang cookie 不可变。用不同的值执行install --force会失败;--etcd-endpoints可以更新。- 单机实例不能转换为集群成员(反之亦然):用
--clean-data删除后重新安装。集群首次安装 也要求数据目录为空。 --advertise-host、--node-id、--peer、--join对 RabbitMQ 不适用;节点身份由--node-name唯一决定。集群模式拒绝明文--admin-password。- 管理员密码是集群级凭据,所有成员必须保存相同的值。轮换时先在管理机执行
pg addon rabbitmq secret generate --force --keep-cookie ...发布新密码(或改用--admin-password-file ...),然后在每个成员上重新执行install --force --secrets-from-etcd(或对应的--admin-password-file ...)。 成员安装后绝不能重新生成 Erlang cookie:它不可变,变化会让install --force失败。 - etcd 中
/pgcli/rabbitmq/clusters/<name>/secrets/下的密钥是明文。请把 etcd client 端口限制在成员主机与管理机之间。这两个密钥只属于集群:AMQP 客户端都不需要 cookie 或 管理员密码,业务应用应创建独立的 RabbitMQ 用户。 - 集群互联流量(
25672上的 Erlang distribution)不加密;--tls只保护客户端监听。 请把4369与25672限制在私有网络,且只对成员开放。
TLS
TLS 是增量的:--tls 保留明文 AMQP 与 management 监听,另外增加 AMQPS 与
management HTTPS。
install 与 status 会同时打印两套端点和 CA 路径:
自动生成的证书由 pgcli 自签 CA(与 MinIO/silo/rustfs、Kafka 共用的 helper)签发,覆盖
localhost、127.0.0.1、::1、宿主所有网卡地址以及具体的 --listen 地址。客户端必须
信任 config/tls/ca.crt:
启用 TLS 后的 AMQP URL(例如 Python/pika 或 Go 客户端):
- TLS 只负责传输加密。
ssl_options.verify = verify_none与fail_if_no_peer_cert = false表示客户端不提供证书;任何能连到已启用端口且知道密码的人 仍然可以访问。监听地址与密码才是安全边界。 - 叶子证书在到期前 30 天内(安装、启动或
--force时)重新签发,CA 保留,因此客户端 不需要换信任文件。该行为只适用于 pgcli 生成的证书。 --tls-port没配--tls会被拒绝。用--tls=false --force关闭 TLS;生成的文件保留在config/tls/,重新启用时复用。
自带证书(pg cert)
--tls-cert 与 --tls-key 必须成对传入,且隐含 --tls。在任何镜像拉取或容器操作之前,
pgcli 会校验:
- 证书可解析且当前有效;
- 允许 server authentication,且不是 CA 证书;
- 私钥与证书匹配且未加密;
- 证书覆盖具体的
--listen地址(不覆盖是硬错误;可改用--listen 0.0.0.0或把该地址 加入 SAN)。
文件会复制到实例的 config/tls/:证书为 public.crt、私钥为 private.key,证书副本同时
作为 ca.crt。pg cert 生成的自签叶子证书本身就是信任锚,客户端可直接信任 rmq.crt。
如果证书由其他 CA 签发,请改为信任该 CA 链:ca.crt 只包含你提供的文件,可能不包含根证书。
使用自带证书时,源文件不会被改动,pgcli 也不会自动续期——替换源文件后重新执行
install --force(或 --tls=false --force 回到明文)。
队列与消息
queue list、purge、delete 走容器内的 rabbitmqctl,不依赖 management HTTP 密码。
其余队列命令——declare、info、publish、get、bind、unbind、bindings——通过
management HTTP API 使用已保存的管理员凭据,要求实例正在运行且宿主能访问 management 端口。
list打印name、type、messages、ready、unacked、consumers;空 vhost 打印no queues。declare在单机实例上默认创建持久化 classic 队列,在集群成员上默认创建 持久化 quorum 队列(见集群)。RabbitMQ 4.x 已移除 transient(非持久化且 非 exclusive)队列,因此--durable=false会在发出请求前直接报错。--type classic或--type quorum可显式覆盖默认类型;quorum 队列必须持久化,且不能 auto-delete。 可重复的--argument KEY=VALUE设置队列参数;能按 JSON 解析的值保留 JSON 类型(如--argument x-max-priority=10)。- 消息保留时间。
--message-ttl 30m(或毫秒数)设置x-message-ttl:在队列中等待超过 该时间的消息会被丢弃;若队列配置了x-dead-letter-exchange则转死信。单条消息也可用--property 'expiration="60000"'设置自己的 TTL。 - 自动删除。
--auto-delete在最后一个消费者断开后删除队列。--expires 24h设置x-expires:队列连续闲置该时长后,队列本身连同其中剩余消息一起删除。只有存在 消费者、被重新声明、或通过basic.get访问才算“使用过”;单纯发布消息不会重置 计时器。该值必须为正数(0会被 RabbitMQ 拒绝)。两者也可通过--argument设置。 info显示 type、state、durable、auto-delete、消息计数、consumers、memory、policy、 arguments 与 node;--json输出 management API 原始文档。计数由 RabbitMQ 统计模块异步 刷新,可能比 publish/get 滞后几秒。publish发送一条消息。--payload与--payload-file必须二选一(-表示 stdin)。--exchange默认amq.default(默认 exchange,按 routing key 直接路由到同名队列);--routing-key默认队列名。可重复的--property KEY=VALUE设置消息属性,例如--property delivery_mode=2 --property 'content_type="application/json"'。消息未被路由时 只打印警告,命令仍成功。- 单机持久化。 单机实例默认声明持久化 classic 队列(不复制),但 durable 只作用于
队列本身,不作用于消息。classic 的消息持久化是每条消息的属性,必须由发布端在每次
publish 时设置:命令行加
--property delivery_mode=2,应用客户端则在 AMQP 发布代码中 设置delivery_mode=2。队列参数或 policy 无法开启该行为(--argument delivery_mode=2不生效)。未设置时消息是 transient,broker 重启(stop/start、 容器重建或宿主机重启)后队列还在、消息丢失。设置后只要实例数据目录保留(不要remove --clean-data),消息即可恢复;磁盘损坏则无法恢复。集群的 quorum 队列不依赖 delivery mode,所有消息都会持久化并复制。 get默认 peek(ack_requeue_true);--consume确认并删除取出的消息 (ack_requeue_false)。--count默认 1;--json输出 API 原始响应。bind/unbind必填--exchange,并拒绝amq.default(默认 exchange 是隐式绑定)。--routing-key默认队列名。可重复的--argument支持基于参数(headers)的绑定。unbind不带--argument时删除该 exchange 下所有同 routing key 的绑定;带--argument时只删除参数完全一致的那条。bindings列出队列的绑定及其参数(--json输出原始文档)。purge清空队列中的消息但保留队列;delete删除队列本身。两者默认要求确认,--yes可跳过。--if-empty/--if-unused(仅 delete)透传 RabbitMQ 的条件检查:队列 非空或有消费者时删除失败,而不是直接删掉。- 所有队列命令都接受
--name与--vhost(默认/),并要求实例正在运行。
限制保留时间样例
不带保留参数的队列会无限期保留消息:默认没有 TTL。消息只会因为被消费、purge、 进入死信,或队列本身被删除而离开。常见限制方式:
--message-ttl 与 --expires 只在队列首次声明时生效。要修改已存在队列的保留策略而不
删除队列,使用 policy:
policy 按队列名正则匹配,对新建和已有队列都生效,并优先于同名的 x-* 队列参数。也可以
在 management UI 的 Admin → Policies 中创建。
同样的保留限制也可以不重新声明队列,直接通过 RabbitMQ policy(message-ttl、
expires、max-length、max-length-bytes)施加;pgcli 暂未封装 policy,请使用
management UI 或 rabbitmqctl set_policy。
pg addon rabbitmq shell 打开容器内的 /bin/bash;rabbitmqctl 与
rabbitmq-diagnostics 都在里面,可处理 CLI 和 API 未覆盖的操作。
状态与生命周期
install、start 与 --force 在单机实例上最多等待 90 秒,轮询
rabbitmqctl -q await_startup;集群成员最多等待 180 秒,覆盖首次 peer discovery
与 Mnesia 引导。集群模式下每次尝试上限 10 秒——有 peer 时该命令可能已执行成功却静默
不退出;若被空闲 watchdog 终止,pgcli 改为探测 AMQP 端口,监听器在启动末尾打开,
端口可连即视为就绪。就绪后 pgcli 用
rabbitmqctl change_password / add_user / set_user_tags administrator /
set_permissions 对账管理员账号。
集群模式下 status 还会打印集群名、Erlang 节点名与 etcd endpoint;
pg addon rabbitmq cluster status 展示 rabbitmqctl cluster_status 的实时视图。
不带 --clean-data 的 remove 会保留数据目录、生成的配置和 0600 密码 secret。同名重装会
复用该密码,因此 remove/reinstall 之后客户端配置无需修改。
开机自启:
启动时会重写 rabbitmq.conf、启动容器并重新对账管理员账号。pg start 也会带上已启用
autostart 的 RabbitMQ 实例。
pgcli 创建的内容
单个实例的全部文件位于 <base_dir>/addon/rabbitmq/<name>/:
| 宿主路径 | 容器路径 | 说明 |
|---|---|---|
config/rabbitmq.conf |
/etc/rabbitmq/rabbitmq.conf(只读) |
渲染后的监听、management、管理员 tags/权限与 distribution 配置 |
config/enabled_plugins |
/etc/rabbitmq/enabled_plugins(只读) |
单机 [rabbitmq_management].;集群 [rabbitmq_management,rabbitmq_peer_discovery_etcd]. |
config/tls/ |
/etc/rabbitmq/tls(只读,仅 --tls) |
ca.crt(0644)、public.crt(含链,0644)、private.key(0600,chown 给 uid 999);ca.key 留在宿主侧且不挂载 |
data/ |
/var/lib/rabbitmq |
Mnesia、消息存储、definitions 与日志;集群模式额外包含 .erlang.cookie(0400,chown 给 uid 999) |
secrets/admin_password |
不挂载 | 0600,重装时复用 |
明文实例生成的 rabbitmq.conf:
--tls 时会额外写入 listeners.ssl.default、ssl_options.* 与 management.ssl.*。
集群成员改为绑定 0.0.0.0(或显式 --listen 地址),并追加发现配置:
任何 secret 都不会写进 rabbitmq.conf。管理员密码通过容器环境变量传入
(RABBITMQ_DEFAULT_USER / RABBITMQ_DEFAULT_PASS 只用于播种空的 Mnesia,之后 pgcli
每次启动用 rabbitmqctl 对账),RABBITMQ_NODENAME 与 RABBITMQ_USE_LONGNAME 同样走
环境变量。集群模式下 pgcli 还会在容器启动之前把共享 Erlang cookie 写入
data/.erlang.cookie(权限 0400,属主 uid 999):官方 4.4 镜像忽略
RABBITMQ_ERLANG_COOKIE,任其自行生成随机 cookie 的节点无法与 peer 完成 distribution
握手。
容器以 --network host、--restart unless-stopped 和 30 秒 stop timeout 运行,身份是镜像的
uid/gid 999(rabbitmq);pgcli 只把 TLS 私钥与集群 cookie 文件交给该 uid(rootless 下
通过 podman unshare,root 下用 os.Chown)。数据目录由镜像入口脚本自行 chown。
配置覆盖
安装时可追加 rabbitmq.conf 条目:
--config-option 替换已存储的覆盖表(不合并)。覆盖项保存在 pg.yaml 的
addons.rabbitmq.<name>.settings 下,每次启动重新渲染。键可包含字母、数字、点、下划线和
连字符;值不能包含 NUL、CR 或 LF。
pgcli 托管的键会被拒绝而不是被静默覆盖:listeners.*、ssl_options.*、management.*、
prometheus.*、cluster_formation.*、default_user、default_pass、
default_user_tags.*、default_permissions.*、loopback_users.*、
distribution.listener.*。
密码与账号语义
RABBITMQ_DEFAULT_USER/RABBITMQ_DEFAULT_PASS只在首次启动、Mnesia 为空时播种。 因此 pgcli 每次启动都用rabbitmqctl change_password对账(用户不存在时退回add_user),再设置administratortag 以及 vhost/上的.* / .* / .*权限。- 在已有实例上修改
--admin-user会创建/对账新账号,但不会删除旧账号。请通过 management UI 或rabbitmqctl delete_user清理。 - 修改
--admin-password(或复用已保存的 secret)会在下一次install --force或start时生效。集群中的密码是共享的:所有成员必须保存相同的值,轮换时要在所有成员上同步操作。 - 集群模式的共享密钥来自
--secrets-from-etcd(推荐,key 由pg addon rabbitmq secret generate写入),或来自--admin-password-file与--erlang-cookie-file。明文--admin-password被拒绝。两个值随后都会持久化到pg.yaml与0600secret 文件。 - 密码同时保存在
pg.yaml与0600secret 文件中;pg addon password rabbitmq --name NAME打印存储值。
生产注意事项
- 单节点或一个集群成员。 单机实例没有 HA:容器停止即 broker 不可用。集群模式的可用性 来自跨成员复制的 quorum 队列;classic 队列不复制,会随所在节点一起不可用。不配置 federation、shovel、MQTT 或 STOMP。
- 集群网络。
4369(EPMD)与25672(Erlang distribution)只在私有网络中、仅对成员 开放。即使启用--tls,distribution 流量也不加密;TLS 只覆盖客户端监听。一台主机只能有 一个集群实例。 - 发现链路是明文的。 etcd endpoint 通过明文 HTTP 访问,没有认证。任何能访问 etcd 的人
都能往集群注册恶意节点,或读取
pg addon rabbitmq secret generate写入的共享密钥; 请把 etcd 隔离在可信网络中。本版本不支持 etcd TLS/认证。 - 不启用 Prometheus 插件。
enabled_plugins固定为 management(集群模式另加 etcd 发现插件)。需要 metrics 时可通过 management API 采集,或自行在容器内启用插件——但要 注意多个实例会争抢同一个默认 metrics 端口。 - TLS 不是客户端认证。 请使用
--listen 127.0.0.1,或在 broker 前加私有网络/防火墙。 Management UI 是完整的管理面,不要随意暴露。 - TLS 是增量监听。 启用
--tls后明文amqp://与http://仍然可用;需要加密的 客户端必须显式选择amqps:///https://端点。 - 升级。
--force --version <new>会拉取新 tag 并在原数据目录上重建容器。RabbitMQ 不保证 能被更新版本写入的数据可降级——升级前请先做离线拷贝。--version必须是真实存在的上游 tag。 - 备份。 停止容器后复制数据目录,或用 management API 导出 users/vhosts/policies 的
definitions。本版本没有
pg addon rabbitmq backup命令。 - 数据属主。 数据文件属 uid/gid 999。请用
--clean-data删除,而不是手工rm;pgcli 会通过podman unshare处理权限回退。 - 平台。 Linux(host 网络);官方镜像为多架构(amd64/arm64)。rootful 宿主上需以 root
运行 pgcli 才能把 TLS 私钥交给 uid 999;rootless 下走
podman unshare。
CLI 参数参考
pg addon install rabbitmq
| 参数 | 默认值 | 说明 |
|---|---|---|
--name NAME |
rabbitmq |
实例名;[A-Za-z0-9][A-Za-z0-9_-]*,最长 48 字符 |
--version TAG |
4.4.0 |
上游 docker.io/library/rabbitmq tag;自动追加 -management 后缀 |
--admin-user USER |
admin |
管理员账号;[A-Za-z0-9_.-]{1,64} |
--admin-password PASS |
自动生成 | 管理员密码(不能含 NUL/CR/LF);集群模式拒绝 |
--admin-password-file FILE |
— | 从文件读取密码;集群成员首次安装必填(使用 --secrets-from-etcd 时除外) |
--data-dir DIR |
<base_dir>/addon/rabbitmq/<name>/data |
绝对宿主路径,挂载到 /var/lib/rabbitmq |
--listen ADDR |
127.0.0.1(集群 0.0.0.0) |
AMQP、AMQPS、management HTTP 与 management HTTPS 的绑定地址;集群模式不能是 loopback |
--cluster NAME |
— | 集群名;空 = 单机 |
--node-name NODE@HOST |
— | 本成员的 Erlang 节点名;首次安装必填 |
--etcd M1,M2 |
— | 用本地 etcd addon 成员做发现 |
--etcd-endpoints HOST:PORT,... |
— | 外部 etcd 发现 endpoint;优先于 --etcd |
--erlang-cookie-file FILE |
— | 从文件读取共享 Erlang cookie;集群成员首次安装必填(使用 --secrets-from-etcd 时除外) |
--secrets-from-etcd |
false | 从 secret generate 写入的 etcd key 读取两个共享密钥;不能与两个 --*-file 同时使用 |
--amqp-port N |
自动(基准 5672) |
明文 AMQP 端口;0 = 自动分配 |
--management-port N |
自动(基准 15672) |
Management HTTP 端口;0 = 自动分配 |
--tls |
false | 增加 AMQPS 与 management HTTPS;明文监听保留 |
--tls-cert FILE |
— | 自带证书链(PEM);必须与 --tls-key 配对;隐含 --tls |
--tls-key FILE |
— | 自带私钥;必须与 --tls-cert 配对 |
--tls-port N |
自动(基准 5671) |
AMQPS 端口;0 = 自动分配;需要 --tls |
--config-option K=V |
— | 额外的 rabbitmq.conf 配置;可重复;替换已存储覆盖表 |
--force |
false | 重写配置并重建容器,保留数据与密码;cluster/node/cookie 不可变 |
pg addon rabbitmq status / shell / cluster ...
| 参数 | 默认值 | 说明 |
|---|---|---|
status --name NAME |
rabbitmq |
显示状态、端点、TLS、管理员、EPMD/dist、路径;集群模式附集群名/节点/etcd |
shell --name NAME |
rabbitmq |
打开容器内 /bin/bash |
cluster status --name NAME |
rabbitmq |
输出 rabbitmqctl cluster_status |
cluster forget NODE --name NAME [--yes] |
— | forget 一个已停止并下线的成员;拒绝本机节点,除非 --yes 否则要求确认 |
pg addon rabbitmq secret generate
| 参数 | 默认值 | 说明 |
|---|---|---|
--cluster NAME |
— | 要发布密钥的集群名(必填) |
--etcd M1,M2 |
— | 保存密钥的本地 etcd addon 成员 |
--etcd-endpoints HOST:PORT,... |
— | 保存密钥的外部 etcd endpoint;优先于 --etcd |
--cookie-file FILE |
/tmp/rmq.cookie |
Erlang cookie 的本地副本(0600);仅集群节点使用,客户端不需要 |
--admin-password-file FILE |
/tmp/rmq.admin |
管理员密码的本地副本(0600);安装输入,不是客户端凭据 |
--force |
false | 覆盖已存在的文件与 etcd key |
--keep-cookie |
false | 与 --force 连用:保留现有 Erlang cookie,只轮换管理员密码(成员已安装后使用) |
pg addon rabbitmq queue ...
所有队列子命令都接受 --name NAME(默认 rabbitmq)与 --vhost VHOST(默认 /)。
| 命令 | 参数 | 默认值 | 说明 |
|---|---|---|---|
list |
— | — | 列出队列及消息/消费者计数 |
declare QUEUE |
--durable |
true | 声明持久化队列(RabbitMQ 4.x 拒绝 false) |
--auto-delete |
false | 最后一个消费者断开后删除队列 | |
--type TYPE |
单机 classic,集群 quorum |
classic 或 quorum |
|
--message-ttl DURATION |
— | 设置 x-message-ttl(如 30m、24h 或毫秒) |
|
--expires DURATION |
— | 设置 x-expires:队列闲置该时长后删除(必须 > 0) |
|
--argument K=V |
— | 额外队列参数;可重复;JSON 值保留类型 | |
info QUEUE |
--json |
false | 输出 management API 原始文档 |
publish QUEUE |
--payload TEXT |
— | 消息体(与 --payload-file 互斥) |
--payload-file FILE |
— | 从文件读取消息体;- 表示 stdin |
|
--exchange NAME |
amq.default |
目标 exchange | |
--routing-key KEY |
队列名 | routing key | |
--property K=V |
— | 消息属性;可重复;单机 classic 消息必须在每次 publish 时设置 delivery_mode=2 才能跨 broker 重启保留(不存在队列级开关);JSON 值保留类型 |
|
get QUEUE |
--count N |
1 | 最多取出的消息数 |
--consume |
false | ack 并删除消息(默认 peek 后重新入队) | |
--json |
false | 输出 management API 原始响应 | |
bind QUEUE |
--exchange NAME |
— | 源 exchange(必填;拒绝 amq.default) |
--routing-key KEY |
队列名 | routing key | |
--argument K=V |
— | 绑定参数;可重复 | |
unbind QUEUE |
--exchange NAME |
— | 源 exchange(必填) |
--routing-key KEY |
队列名 | routing key | |
--argument K=V |
— | 仅删除参数完全一致的绑定;省略则删除所有匹配项 | |
bindings QUEUE |
--json |
false | 输出 management API 原始文档 |
purge QUEUE |
--yes |
false | 跳过确认提示 |
delete QUEUE |
--yes |
false | 跳过确认提示 |
--if-empty |
false | 队列非空时失败而不是删除 | |
--if-unused |
false | 队列有消费者时失败而不是删除 |
生命周期、日志、autostart
| 命令 | 参数 | 说明 |
|---|---|---|
pg addon start rabbitmq |
--name NAME |
启动(缺失则创建),等待就绪并对账管理员 |
pg addon stop rabbitmq |
--name NAME |
停止容器,保留数据 |
pg addon remove rabbitmq |
--name NAME、--clean-data |
删除容器与配置条目;--clean-data 同时删除实例目录与自定义 data dir |
pg logs addon rabbitmq |
--name NAME、-n N(默认 50)、-f |
容器日志 |
pg autostart enable|disable |
--rabbitmq、--name NAME |
切换单个实例的开机自启 |
pg addon password rabbitmq |
--name NAME |
打印存储的管理员密码 |
全局参数
| 参数 | 说明 |
|---|---|
-c, --config FILE |
配置文件(默认 ~/.pgcli/pg.yaml) |
-o, --output FILE |
输出配置路径(默认与输入相同) |
-i, --instance NAME |
PostgreSQL 实例选择器——RabbitMQ 不使用,请用 --name |