跳转到主要内容

RocketMQ

以托管插件方式运行 Apache RocketMQ 5.x——三容器(NameServer + broker + proxy),支持单机或跨主机 controller 模式集群与 broker 自动主备切换,含 topic/消息命令、渲染配置与 host 网络

pg addon install rocketmq 以托管插件方式运行 Apache RocketMQ 5.x,使用官方 docker.io/apache/rocketmq 镜像。和 Kafka、ClickHouse、RabbitMQ 一样,它是顶层插件, 不代理某个 PostgreSQL 实例。

每个实例都是 host 网络上的三个容器:NameServer、broker 和 proxy。单机与 集群使用相同的形态,因此端口、命令、日志和生命周期行为保持一致:

  • 单机——一个不带 controller 的 NameServer、一个无副本的 async master broker,以及 proxy。这是最快能收发消息的模式。不使用 4.x 的 master/slave 或 DLedger broker 部署模式。
  • 跨主机集群——每个 NameServer 内嵌 DLedger(Raft)controller,broker 以 controller 模式运行:一个 broker 被选为 master,故障时另一个自动接管;proxy 作为 客户端入口。这是 RocketMQ 5.x 的自动切换部署模式。

没有认证,也没有 TLS。 RocketMQ 使用 host 网络监听,集群端口固定。任何能连到 NameServer、broker 或 proxy 端口的人都可以读写所有 topic。只应在可信内网或防火墙之后 运行,并限制 9876、9877、10911、10912、8080、8081。本插件也没有 Web UI 和 ACL。

参数

参数 默认值 说明
--name rocketmq 实例名(配置 map 的 key,也是子命令的默认实例名)
--version 5.5.0 上游镜像 tag,镜像为 docker.io/apache/rocketmq:<version>;只接受 5.x
--data-dir <base_dir>/addon/rocketmq/<name>/data 实例数据根目录:broker store 为 <dir>/broker,集群模式的 controller store 为 <dir>/controller;除相对 base_dir 外必须是绝对路径
--advertise-host 单机 127.0.0.1;集群必填 向客户端和对端通告的地址。集群模式必须是非 loopback 的具体 IPv4 地址;主机名、IPv6 和 0.0.0.0 都会被拒绝。单机若需远程客户端访问,应设置为宿主机的局域网 IP
--cluster NAME — 开启跨主机集群模式。每台主机必须使用相同名称;它同时作为 DLedger controller group 和 broker cluster/group 名。集群身份安装后不可变
--controller-id ID — 本节点的 controller 成员 id(n0、n1……)。集群首次安装必填,组内唯一,匹配 [A-Za-z][A-Za-z0-9]{0,31};单机模式拒绝
--peer ID@HOST — 另一个 controller 成员。按其他节点逐条重复,host 为裸的非 loopback IPv4、不带端口(controller 端口固定 9877)。每台主机都要传入其他成员的完整列表;本地成员会自动补全。单机模式拒绝
--namesrv-port 单机自动(9876) NameServer 主机端口;0 = 从 RocketMQ 端口池自动分配。仅单机可用,集群成员固定 9876
--broker-port 单机自动(10911) broker 监听端口;HA 端口为 broker_port + 1,VIP 端口为 broker_port - 2。仅单机可用,集群成员固定 10911
--proxy-port 单机自动(8080) proxy remoting 端口。仅单机可用,集群成员固定 8080
--grpc-port 单机自动(8081) proxy gRPC 端口(5.x SDK)。仅单机可用,集群成员固定 8081
--controller-port — 内嵌 controller 端口。单机模式不接受;集群成员固定 9877
--heap 512m broker JVM 堆,写入 JAVA_OPT_EXT=-Xms<size> -Xmx<size>
--namesrv-heap 256m NameServer JVM 堆
--proxy-heap 256m proxy JVM 堆
--config-option K=V — 追加到 broker.conf 的设置(flushDiskType=SYNC_FLUSH、brokerPermission=4);可重复,且替换已存储的覆盖列表。pgcli 托管的键会被拒绝(身份、监听、store 路径、controller 设置、复制设置、autoCreateTopicEnable)
--force false 重新渲染三个配置并重建三个容器,保留 broker store 和 controller store。集群身份和固定端口即使加 --force 也不能修改

--image、--listen、--tls、--tls-pem、--tls-cert、--tls-key、--node-id、 --cluster-id、--join 均不适用于 RocketMQ,会被拒绝。选择镜像请使用 --version。

安装单机实例

pg addon install rocketmq --name rmq

安装会按需拉取镜像、渲染配置、创建目录,按 namesrv → broker → proxy 启动,并等待 NameServer、broker 注册和两个 proxy 监听端口就绪:

✓ RocketMQ "rmq" installed
  Version:     5.5.0
  Image:       docker.io/apache/rocketmq:5.5.0
  Containers:  pgcli-rocketmq-rmq-namesrv, pgcli-rocketmq-rmq-broker, pgcli-rocketmq-rmq-proxy
  Namesrv:     127.0.0.1:9876
  Broker:      127.0.0.1:10911 (HA 10912, VIP 10909)
  Proxy:       127.0.0.1:8080 (remoting), 127.0.0.1:8081 (gRPC)
  Mode:        single-node (no controller, no replicas)
  JVM heap:    broker 512m, namesrv 256m, proxy 256m
  Data dir:    /home/you/.pgcli/addon/rocketmq/rmq/data
  Config:      /home/you/.pgcli/addon/rocketmq/rmq/config

若需要其他主机上的客户端访问,应通告宿主机的局域网地址(proxy 配置和 broker 都使用它):

pg addon install rocketmq --name rmq --advertise-host 10.0.0.11

第二个单机实例会从各端口池取下一个空闲端口,不会复用第一个实例的端口:

pg addon install rocketmq --name rmq2 --data-dir /srv/rocketmq-data

在内存较小的 VM 上,降低三个 JVM 的堆,避免三个进程超出内存:

pg addon install rocketmq --name rmq \
  --heap 384m --namesrv-heap 192m --proxy-heap 192m

不带 --force 重复执行 install 是空操作,只报告当前状态。带 --force 时,pgcli 会重写 namesrv.conf、broker.conf 和 rmq-proxy.json,重建三个容器,并保留 broker store 与 controller store。

多机集群

集群模式使用 RocketMQ 5.x 的 controller 模式:controller 以 DLedger(Raft)group 的 形式内嵌在每个 NameServer 中,controller 模式的 broker 选举 master 并在故障时自动切换。 每台主机各自执行一次 pg addon install rocketmq;pgcli 不会 SSH 到其他主机。

要求:

  • 每台主机的 --cluster 名称相同。
  • 每台主机使用唯一的 --controller-id(n0、n1、n2……)。
  • 本机的 --advertise-host 是具体的非 loopback IPv4 地址。
  • --peer ID@HOST 列出其他 controller 成员;每台主机都要传完整对端集合,本地成员会 自动补全。
  • 每台主机上的固定集群端口空闲:9876、9877、10911、10912、8080、8081。 一台主机只能运行一个集群 RocketMQ 实例。
  • 至少 3 个成员才有容错。 DLedger 的 quorum 是多数派,2 个成员无法容忍任何故障; pgcli 会为 2 成员集群打印 warning。

逐台安装。以 10.0.0.11、10.0.0.12、10.0.0.13 三台主机为例:

# 在 10.0.0.11 上(controller n0)
pg addon install rocketmq --name rmq --cluster prod --controller-id n0 \
  --advertise-host 10.0.0.11 \
  --peer n1@10.0.0.12 --peer n2@10.0.0.13

# 在 10.0.0.12 上(controller n1)
pg addon install rocketmq --name rmq --cluster prod --controller-id n1 \
  --advertise-host 10.0.0.12 \
  --peer n0@10.0.0.11 --peer n2@10.0.0.13

# 在 10.0.0.13 上(controller n2)
pg addon install rocketmq --name rmq --cluster prod --controller-id n2 \
  --advertise-host 10.0.0.13 \
  --peer n0@10.0.0.11 --peer n1@10.0.0.12

前两台安装预计会以 warning 结束:

[!] RocketMQ broker is running, but it has not registered with the controller yet
(broker not listed in clusterList) — install the remaining nodes with the same
--cluster and --peer values ...

这是正常现象:只有多数 NameServer 起来后 controller quorum 才会形成。安装仍会成功返回, 容器保持运行。第三台安装完成后,controller 选出 broker master,broker 完成注册。

逐台检查:

pg addon rocketmq status --name rmq
pg addon rocketmq cluster status --name rmq

status 显示三个容器状态、controller id、完整 peer 列表,以及集群可达时已注册的 broker 数和 master 数。cluster status 原样输出 clusterList 表格;controller 分配的 BID 列(旧版客户端里叫 BrokerId)中,当前 master 为 0,副本为非 0:

rocketmq "rmq" — cluster prod: 3 broker(s), 1 master(s)
#Cluster Name  #Broker Name  #BID  #Addr             #Version  #InTPS(LOAD)  #OutTPS(LOAD)
prod           prod          0     10.0.0.13:10911   V5_5_0    0.00(0,0ms)   0.00(0,0ms)
prod           prod          1     10.0.0.11:10911   V5_5_0    0.00(0,0ms)   0.00(0,0ms)
prod           prod          2     10.0.0.12:10911   V5_5_0    0.00(0,0ms)   0.00(0,0ms)

列布局和行顺序由 mqadmin 产生,不同 5.x 版本可能略有差异;pgcli 只依赖 cluster 名和 broker id 列。

主备切换

master broker 停止后,controller 在心跳超时后从 in-sync 副本中选出新 master。通过 proxy 或 NameServer 连接的客户端会自动重试。观察一次切换:

# 在 cluster status 中找到 BID 0 所在主机,然后在该主机上:
pg addon stop rocketmq --name rmq

# 在任一成员上轮询,直到出现新的 BID 0:
pg addon rocketmq cluster status --name rmq

# 重新启动旧 broker;它会以副本身份重新加入:
pg addon start rocketmq --name rmq

配置中渲染了 enableElectUncleanMaster=false,不在 in-sync state set 中的副本不会被选为 master。如果 controller quorum 本身失去多数派(例如三台 NameServer 中两台停止),就无法 选出 master,写入会一直阻塞到 quorum 恢复。停止或移除一个成员不会改写其他主机上的 peer 列表;pgcli 不会联系其他节点。

端口

端口 角色 单机 集群
9876 NameServer 客户端/RPC 自动,基准 9876 固定
9877 内嵌 DLedger controller 不使用 固定
10911 broker 监听 自动,基准 10911 固定
10912 broker HA 复制 broker_port + 1 固定
10909 broker VIP broker_port - 2 固定
8080 proxy remoting 自动,基准 8080 固定
8081 proxy gRPC 自动,基准 8081 固定

单机实例可以从端口池分配端口并连同派生的 HA/VIP 端口一起保留,因此一台主机上可共存多个 实例。集群模式所有端口固定,因为 controller 成员关系和 broker 地址会写入每个节点的配置。

客户端

两种模式下 proxy 都是客户端入口,并以 CLUSTER 模式运行:

  • 5.x gRPC SDK(推荐的 5.x 客户端):连接 <advertise-host>:8081。
  • Remoting SDK(4.x 风格客户端):连接 <advertise-host>:8080,或直接连接 broker <advertise-host>:10911。
  • NameServer 地址(9876、controller 9877)是集群内部通信地址,不要暴露给远程客户端。

单机默认 127.0.0.1,其他主机上的客户端需要使用设置了 --advertise-host 的安装。集群模式 每台成员都要求非 loopback 的 IPv4 --advertise-host,各主机上的 proxy 通告本机地址。

Topic 与消息

为兼容启用了 topic 自动创建(autoCreateTopicEnable=true),但建议显式创建,以保证队列数 可预期:

pg addon rocketmq topic create surge --queues 3 --name rmq
pg addon rocketmq topic list --name rmq
pg addon rocketmq topic describe surge --name rmq

topic create 在整个集群上创建 topic(-c <cluster-or-name>),--queues 同时设置读写 队列数(默认 3)。topic list 默认隐藏 RocketMQ 内部 topic(%RETRY%…、%DLQ%…、 TBW102、SELF_TEST_TOPIC、事务/调度/trace topic、5.x 的 rmq_sys_* / RMQ_SYS_*、 *_REPLY_TOPIC 以及以 cluster 名命名的内部 topic);加 --system 显示全部。 topic describe 输出 topicStatus 的按 broker 队列和 offset 表。

发送一条消息并按 key 查询:

pg addon rocketmq send surge "hello" --key k1 --tags demo --name rmq

pg addon rocketmq shell --service namesrv --name rmq -- \
  sh mqadmin queryMsgByKey -t surge -k k1 -n 127.0.0.1:9876

send 会打印 sendMessage 结果,包括 message id、发送状态和队列。用带边界的一次性调试消费者把消息拉回来:

pg addon rocketmq consume surge --count 10 --timeout 30s --name rmq

# 只读一个队列,从起始 offset 开始
pg addon rocketmq consume surge --queue 0 --offset 0 --count 50 --name rmq

# 按时间窗口读取(epoch 毫秒或 yyyy-MM-dd#HH:mm:ss:SSS)
pg addon rocketmq consume surge --begin 1793264528000 --end 1793264535000 \
  --count 0 --name rmq

consume 在一次性容器里运行 mqadmin consumeMessage,把消息打印到终端。它把 topic 各队列当前的消息拉完就退出;--timeout(默认 30s)是容器内的硬性安全上限,Ctrl-C 可提前结束。它只做拉取和打印,不删除消息,也不提交消费位点。

--count 是 mqadmin 的消息预算(默认 10);mqadmin 按队列计算,实际打印的条数可能略少于请求值,--count 0 表示不设预算。--queue/--offset 只读一个队列,broker 名默认取实例的单 broker 名(--broker 可覆盖)。--begin/--end 接受 epoch 毫秒或 yyyy-MM-dd#HH:mm:ss:SSS;mqadmin 会把时间边界换算成队列 offset,因此结束边界可能包含恰好在其后的一条消息。

删除 topic 会删掉它的所有消息,除非加 --yes,否则会先要求确认:

pg addon rocketmq topic delete surge --name rmq --yes

消息保留

消费不会删除消息。broker 以 commitlog 段(同一 broker 上所有 topic 共用的存储单位)为 单位删除:段年龄超过 fileReservedTime 小时,并且时钟到达 deleteWhen 指定的整点时 删除;磁盘占用超过 diskMaxUsedSpaceRatio 百分比时提前删除。保留策略是 broker 级别的, 不能按 topic 单独设置。

查看运行中 broker 的实际值并修改:

pg addon rocketmq retention show --name rmq

pg addon rocketmq retention set --hours 24 --delete-when "04;16" \
  --disk-ratio 80 --name rmq

默认值为 72 小时、04 点、75%。set 至少要给一个参数:--hours(1–8760)、 --delete-when(一个或多个 0–23 的整点,用 ; 分隔)、--disk-ratio(1–100)。 它通过 updateBrokerConfig 立即修改运行中的 broker,并把相同的值写入 pg.yaml 和 重新渲染的 broker.conf,因此 pg addon stop/start 后仍然生效,无需重建容器。 过期段不保证在整点立刻删除,而是在 broker 下一次调度清理时移除。把比例调高到当前磁盘 占用以上可以停止磁盘压力触发的提前删除。

保留策略按 broker 保存。集群中要在每台成员主机上分别执行;每个 broker 只清理自己的 commitlog。

投递与持久性

单机。 broker 是唯一节点(brokerId=0、brokerRole=ASYNC_MASTER),没有副本。消息写入 data/broker 下的 broker store,因此优雅停止/启动不会丢失。渲染的刷盘策略是 RocketMQ 默认的 ASYNC_FLUSH,宿主机掉电可能丢失最近的写入。需要更强持久性时渲染 SYNC_FLUSH(会降低 吞吐):

pg addon install rocketmq --name rmq --force \
  --config-option flushDiskType=SYNC_FLUSH

集群。 broker 以 controller 模式复制。pgcli 渲染 allAckInSyncStateSet=true,3 个及以上 成员时 minInSyncReplicas=2(2 成员时为 1),因此只有所有 in-sync 副本都接受消息后 produce 才会成功。刷盘默认仍是 ASYNC;如果要求所有副本同时掉电也不丢已确认写入,请使用 flushDiskType=SYNC_FLUSH。

复制保护的是 controller quorum 健康时的 broker 故障,并不意味着 controller store 可以 随意删除:data/controller 保存 DLedger 状态和 epoch 文件。删除它、清空成员,或用 --clean-data 重装,都会破坏该成员的 controller 状态,并可能破坏 quorum。被移除后重新加入 的成员必须以空数据目录启动,并使用相同的 cluster/controller/peer 身份。

pg addon remove rocketmq --clean-data 会删除实例目录(配置、broker store、controller store 和日志)以及独立的自定义数据目录。不带 --clean-data 时会保留数据和配置目录。

配置、升级与不可变性

  • 加 --force 可修改: 版本、JVM 堆、broker.conf 覆盖项,以及单机实例的监听端口。 --config-option 会替换已存储的覆盖 map,强制重装时需重新传入全部覆盖项。
  • 即使加 --force 也不可修改: 集群模式的 --cluster、--controller-id、 --advertise-host、--peer 和固定端口。这些值已写入每个对端的配置,原地修改会被拒绝。
  • 拓扑变更必须重建: 单机 ↔ 集群不是原地变更。使用 --clean-data 删除实例后,按目标 模式重新安装。
  • 自定义数据目录: 把 --data-dir 指向新路径会使用新的空 store;pgcli 不会迁移已有数据。

pgcli 托管的 broker.conf 键(在 --config-option 中会被拒绝)包括 brokerClusterName、brokerName、brokerId、brokerRole、brokerIP1/brokerIP2、 listenPort、haListenPort、namesrvAddr、enableControllerMode、controllerAddr、 所有 controller* 键、storePathRootDir、storePathCommitLog、storePathEpochFile、 autoCreateTopicEnable、allAckInSyncStateSet、minInSyncReplicas、 enableControllerInNamesrv、enableElectUncleanMaster、notifyBrokerRoleChanged。

生命周期、日志与开机自启

pg addon start rocketmq --name rmq
pg addon stop rocketmq --name rmq
pg addon remove rocketmq --name rmq --clean-data

pg logs addon rocketmq --name rmq --service broker -f
pg logs addon rocketmq --name rmq --service namesrv
pg logs addon rocketmq --name rmq --service proxy

停止按逆序(proxy → broker → namesrv),启动按正序(namesrv → broker → proxy)。集群模式 的启动不等待 controller quorum:多数派尚未可达时,broker 会保持等待状态,命令仍会成功返回。 其他成员起来后,用 pg addon rocketmq status 和 cluster status 确认。

开机自启与其他顶层插件一致:

pg autostart enable --rocketmq --name rmq
pg autostart status

它会重新渲染三个配置并按顺序启动容器。对于集群成员,自启不等待 controller quorum,因此各 成员可以任意顺序启动。pg addon start(全局自启启动器)行为相同。

限制

  • 没有认证、TLS 或 ACL。 请限制网络;proxy 和 NameServer 对任何能连到端口的人开放。
  • 没有 Web UI。 使用 pg addon rocketmq status、cluster status、topic 命令和日志。
  • 不支持在线扩缩容或滚动升级。 集群成员关系和固定端口不可变;成员变更需要有计划地重建。 成员仍在 quorum 中时不能删除其 controller store。
  • 2 成员集群没有容错能力。 生产环境请使用 3 个及以上成员。
  • 仅 Linux。 插件依赖 host 网络和官方镜像的 uid/gid 3000。
  • 不做消息迁移、consumer group 管理或 broker/storage 重平衡。 可通过 pg addon rocketmq shell 使用标准 RocketMQ 管理工具。