This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 95f37df8 feat: add docker compose test cluster with message trace for 
local debugging (#655)
95f37df8 is described below

commit 95f37df8ee9e6066f6d51714374977bcd3e60d93
Author: lizhimins <[email protected]>
AuthorDate: Wed Jul 29 14:11:54 2026 +0800

    feat: add docker compose test cluster with message trace for local 
debugging (#655)
---
 .claude/skills/deploy-rocketmq/SKILL.md    | 144 +++++++++++++++++++++++++++++
 deploy/rocketmq/Dockerfile                 |  48 ++++++++++
 deploy/rocketmq/README.md                  |  70 ++++++++++++++
 deploy/rocketmq/build.sh                   |  24 +++++
 deploy/rocketmq/clients/TraceConsumer.java |  24 +++++
 deploy/rocketmq/clients/TraceProducer.java |  32 +++++++
 deploy/rocketmq/conf/broker-0.conf         |  15 +++
 deploy/rocketmq/conf/broker-1.conf         |  15 +++
 deploy/rocketmq/conf/rmq-proxy.json        |   7 ++
 deploy/rocketmq/docker-compose.yml         | 112 ++++++++++++++++++++++
 10 files changed, 491 insertions(+)

diff --git a/.claude/skills/deploy-rocketmq/SKILL.md 
b/.claude/skills/deploy-rocketmq/SKILL.md
new file mode 100644
index 00000000..6097df84
--- /dev/null
+++ b/.claude/skills/deploy-rocketmq/SKILL.md
@@ -0,0 +1,144 @@
+---
+name: deploy-rocketmq
+description: 部署 studio 测试集群。从 Apache RocketMQ 开源 develop 分支源码构建镜像,用 docker 
compose 在本地拉起 NameServer + 双 Broker + Proxy 集群,并启动 1 TPS 持续收发消息的 Producer / 
Consumer(均开启消息轨迹)。当用户说 部署 studio 测试集群 时触发。
+---
+
+# 部署 studio 测试集群
+
+在本地用 docker compose 部署一套开源 RocketMQ 集群(NameServer + 双 Broker + Proxy),
+集群名 `rocketmq-studio`,Broker 开启消息轨迹,附带 Producer / Consumer 容器以
+1 TPS 持续收发消息并上报轨迹,供 RocketMQ Studio 本地调试使用。
+
+所有部署产物在 `deploy/rocketmq/` 目录,详见其中的 `README.md`。
+
+## 前置条件
+
+- 已安装 `docker`(含 `docker compose`)。
+- 网络可访问 `github.com`(构建阶段 git clone);国内环境由 `build.sh` 自动切换
+  apt / Maven 阿里源。
+- 宿主机端口 9876、10909、10911、10912、10919、10921、10922、8080、8081 未被占用
+  (与 studio 主 compose 的端口约定一致,不冲突)。
+
+## 执行步骤
+
+### 1. 构建镜像
+
+```bash
+cd deploy/rocketmq
+./build.sh          # 自动判断地理位置:国内走阿里源,国外用默认源
+```
+
+- Dockerfile 为多阶段构建:builder 阶段 `git clone --depth 1 -b develop
+  https://github.com/apache/rocketmq.git` 后执行
+  `mvn -Prelease-all -DskipTests clean install`,运行阶段仅保留
+  `bin/ conf/ lib/` 产物,基础镜像 `alibabadragonwell/dragonwell:17-anolis`(yum 
系,国内拉取快)。
+- 首次构建需 10-20 分钟;如需指定其他分支或 tag:
+  `docker build --build-arg ROCKETMQ_BRANCH=rocketmq-all-5.5.0 -t 
apache-rocketmq:develop .`
+
+### 2. 拉起集群
+
+```bash
+docker compose up -d
+```
+
+服务说明:
+
+| 服务 | 说明 |
+|------|------|
+| nameserver | `mqnamesrv`,端口 9876 |
+| broker-0 / broker-1 | `mqbroker -c broker-{0,1}.conf`,集群 
`rocketmq-studio`,broker 名 `rocketmq-studio-{0,1}`,各限 1C2G,已开启 
`traceOn=true`、`traceTopicEnable=true` |
+| proxy | `mqproxy -pc rmq-proxy.json`,集群模式,remoting 8080 / gRPC 8081,1C2G,已关闭 
topic 消息类型校验(`enableTopicMessageTypeCheck=false`,避免自动建 topic 类型为 UNSPECIFIED 
时发送被拒) |
+| producer | 编译并运行 `clients/TraceProducer.java`,1 TPS 发送到 `StudioTest`(带 Key 
`studio-key-<n>`),`enableMsgTrace=true`,接入点 `proxy:8080`(流量经 proxy 转发) |
+| consumer | 编译并运行 `clients/TraceConsumer.java`,Push 消费 
`StudioTest`,`enableMsgTrace=true`,接入点 `proxy:8080` |
+
+- 两个 broker 容器内都监听 10909/10911/10912,broker-1 的宿主机端口错开为
+  10919/10921/10922 避免冲突;容器网络内互访始终走 `broker-{0,1}:10911`。
+- 堆内存通过 `JAVA_OPT_EXT` 环境变量收敛(开源启动脚本会将其追加到 JVM 参数末尾,
+  覆盖脚本内置的大堆默认值),适合本地小内存环境。
+- producer / consumer 直接用运行镜像自带 JDK + `lib/*` 依赖现场编译,无需额外构建。
+
+### 3. 验证
+
+```bash
+# 全部容器 Up
+docker compose ps
+
+# 收发日志:producer 每秒一条 SEND_OK,consumer 对应 consume
+docker compose logs -f producer consumer
+
+# 集群注册正常:应看到 rocketmq-studio 下两个 broker
+docker compose exec nameserver sh bin/mqadmin clusterList -n nameserver:9876
+
+# 消息轨迹已落盘(RMQ_SYS_TRACE_TOPIC 有数据即轨迹链路打通)
+docker compose exec broker-0 sh bin/mqadmin consumeMessage \
+  -n nameserver:9876 -t RMQ_SYS_TRACE_TOPIC -c 5
+```
+
+验证通过标准:clusterList 能看到 `rocketmq-studio` 集群下 `rocketmq-studio-0`、
+`rocketmq-studio-1` 两个 broker;producer 日志持续输出 `SEND_OK`;
+`RMQ_SYS_TRACE_TOPIC` 能消费出轨迹数据。
+
+### 4. 清理
+
+```bash
+docker compose down -v
+```
+
+## 常用查询命令(mqadmin)
+
+以下命令均已实测可用,在任意集群容器内执行(示例用 nameserver)。
+msgId / Key 可从 producer 日志获取:`send #16 SEND_OK <msgId> key=studio-key-16`。
+
+### 查看集群状态 clusterList
+
+```bash
+docker compose exec nameserver sh bin/mqadmin clusterList -n nameserver:9876
+```
+
+输出每个 broker 的地址、版本、InTPS/OutTPS(本集群稳态约 1.0,对应 1 TPS 收发)、
+磁盘水位等。`#ACTIVATED=true` 表示 broker 心跳正常。
+
+### 按 msgId 精确查消息 queryMsgByUniqueKey
+
+```bash
+docker compose exec nameserver sh bin/mqadmin queryMsgByUniqueKey \
+  -n nameserver:9876 -t StudioTest -i <msgId>
+```
+
+- `-i` 传客户端 msgId(即 UNIQ_KEY,producer 日志里那个)。
+- 输出 Topic、Tags、Keys、Queue、Born/Store 时间与主机、Properties(可看到
+  `TRACE_ON=true`),消息体落盘到 `/tmp/rocketmq/msgbodys/` 可直接查看。
+
+### 查消息轨迹 queryMsgTraceById
+
+```bash
+docker compose exec nameserver sh bin/mqadmin queryMsgTraceById \
+  -n nameserver:9876 -i <msgId>
+```
+
+- 从 `RMQ_SYS_TRACE_TOPIC` 检索该消息的轨迹:Pub(发送)与 Sub(消费)记录,
+  含消费组、客户端地址、耗时、成功与否。
+- 轨迹是客户端异步批量上报的,消息发送后需等几秒才能查到;
+  只有 Pub 没有 Sub 说明消费轨迹尚未上报或消费未发生。
+
+### 按业务 Key 查消息 queryMsgByKey
+
+```bash
+docker compose exec nameserver sh bin/mqadmin queryMsgByKey \
+  -n nameserver:9876 -t StudioTest -k studio-key-16
+```
+
+- 依赖发送时 `msg.setKeys(...)` 建立的索引(本集群 producer 已设置
+  `studio-key-<序号>`),返回命中的 msgId、Queue、Offset。
+- 拿到 msgId 后可再用 `queryMsgByUniqueKey` / `queryMsgTraceById` 深挖详情与轨迹。
+
+## 常见问题
+
+- **producer 启动初期报 route not found / 类型校验失败**:broker 注册与 topic
+  自动创建需要几秒,发送循环与 `restart: on-failure` 会自动重试,稍等即可。
+- **宿主机客户端连不上 broker**:`brokerIP1=broker-{0,1}` 仅容器网络内可达;
+  宿主机直连需改 `conf/broker-{0,1}.conf` 为 `brokerIP1=127.0.0.1` 并重启。
+  Studio 后端若跑在另一个 compose 网络中,建议共享同一个 docker network。
+- **构建阶段 clone 慢或失败**:确认能访问 github.com,或用
+  `--build-arg ROCKETMQ_REPO=<镜像仓库地址>` 换源;Maven 慢用 `./build.sh`
+  自动切阿里源。
diff --git a/deploy/rocketmq/Dockerfile b/deploy/rocketmq/Dockerfile
new file mode 100644
index 00000000..9b603ed5
--- /dev/null
+++ b/deploy/rocketmq/Dockerfile
@@ -0,0 +1,48 @@
+# 从源码构建 Apache RocketMQ 开源镜像(默认 develop 分支)
+# 用法: ./build.sh(自动判断地理位置,国内走阿里源)
+#       或 docker compose build,可用 --build-arg 
ROCKETMQ_BRANCH=rocketmq-all-5.5.0 指定分支/tag
+
+FROM maven:3.9-eclipse-temurin-17 AS builder
+
+ARG ROCKETMQ_REPO=https://github.com/apache/rocketmq.git
+ARG ROCKETMQ_BRANCH=develop
+# true 时 apt / Maven 走阿里镜像源(国内网络加速),由 build.sh 自动探测
+ARG USE_CN_MIRROR=false
+
+RUN if [ "$USE_CN_MIRROR" = "true" ]; then \
+        sed -i 's|http://archive.ubuntu.com|https://mirrors.aliyun.com|g; 
s|http://security.ubuntu.com|https://mirrors.aliyun.com|g' \
+            /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list 
2>/dev/null || true; \
+        mkdir -p /root/.m2 && printf '%s\n' \
+            '<settings><mirrors><mirror>' \
+            '<id>aliyun</id><mirrorOf>central</mirrorOf>' \
+            '<url>https://maven.aliyun.com/repository/public</url>' \
+            '</mirror></mirrors></settings>' > /root/.m2/settings.xml; \
+    fi
+
+RUN apt-get update && apt-get install -y --no-install-recommends git \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN git clone --depth 1 -b ${ROCKETMQ_BRANCH} ${ROCKETMQ_REPO} /build/rocketmq
+
+WORKDIR /build/rocketmq
+RUN mvn -Prelease-all -DskipTests -Dspotbugs.skip=true -Dcheckstyle.skip=true \
+        -Dmaven.javadoc.skip=true -T 2C clean install \
+    && mkdir /dist \
+    && cp -r distribution/target/rocketmq-*/rocketmq-*/* /dist/
+
+FROM alibabadragonwell/dragonwell:17-anolis
+
+# RocketMQ 启动脚本依赖 JAVA_HOME,构建期断言基础镜像已正确设置
+RUN test -x "$JAVA_HOME/bin/java" && test -x "$JAVA_HOME/bin/javac" \
+    && useradd -m rocketmq
+COPY --from=builder --chown=rocketmq:rocketmq /dist /home/rocketmq
+# 预创建 store/logs 并赋属主,命名卷首次初始化会继承镜像内目录的属主
+RUN mkdir -p /home/rocketmq/store /home/rocketmq/logs \
+    && chown -R rocketmq:rocketmq /home/rocketmq/store /home/rocketmq/logs
+
+USER rocketmq
+WORKDIR /home/rocketmq
+ENV ROCKETMQ_HOME=/home/rocketmq
+
+# 9876 namesrv | 10909/10911/10912 broker | 8080 proxy remoting | 8081 proxy 
grpc
+EXPOSE 9876 10909 10911 10912 8080 8081
diff --git a/deploy/rocketmq/README.md b/deploy/rocketmq/README.md
new file mode 100644
index 00000000..b72c1151
--- /dev/null
+++ b/deploy/rocketmq/README.md
@@ -0,0 +1,70 @@
+# RocketMQ 开源集群本地部署(docker compose)
+
+从 Apache RocketMQ 开源 develop 分支源码构建镜像,用 docker compose 拉起
+NameServer + 双 Broker + Proxy(集群名 `rocketmq-studio`),并附带 1 TPS
+持续收发消息的 Producer / Consumer 容器(均开启消息轨迹),供 RocketMQ Studio
+本地调试使用。
+
+## 目录结构
+
+```
+deploy/rocketmq/
+├── Dockerfile              # git clone develop 分支 + Maven 构建,多阶段产出运行镜像
+├── build.sh                # 构建入口:自动判断地理位置,国内走阿里源
+├── docker-compose.yml      # nameserver / broker-0 / broker-1 / proxy / 
producer / consumer
+├── conf/
+│   ├── broker-0.conf       # rocketmq-studio-0,traceOn + traceTopicEnable 开启轨迹
+│   ├── broker-1.conf       # rocketmq-studio-1,同上
+│   └── rmq-proxy.json      # Proxy 集群模式,指向 nameserver:9876,关闭 topic 类型校验
+└── clients/
+    ├── TraceProducer.java  # 1 TPS 发送(带 Key),enableMsgTrace=true,经 proxy:8080 
接入
+    └── TraceConsumer.java  # Push 消费,enableMsgTrace=true,经 proxy:8080 接入
+```
+
+## 快速开始
+
+```bash
+cd deploy/rocketmq
+
+# 1. 构建镜像(首次约 10-20 分钟,含 clone + mvn 编译;国内自动切阿里源)
+./build.sh
+
+# 2. 拉起集群与收发客户端
+docker compose up -d
+
+# 3. 观察收发日志(1 TPS)
+docker compose logs -f producer consumer
+```
+
+## 验证
+
+```bash
+# 集群状态:rocketmq-studio 下两个 broker
+docker compose exec nameserver sh bin/mqadmin clusterList -n nameserver:9876
+
+# 消息轨迹数据(轨迹写入 RMQ_SYS_TRACE_TOPIC)
+docker compose exec broker-0 sh bin/mqadmin consumeMessage \
+  -n nameserver:9876 -t RMQ_SYS_TRACE_TOPIC -c 5
+```
+
+更多查询命令(queryMsgByUniqueKey / queryMsgTraceById / queryMsgByKey)见
+`.claude/skills/deploy-rocketmq/SKILL.md`。
+
+## 接入端点
+
+| 组件 | 容器内地址 | 宿主机地址 |
+|------|-----------|-----------|
+| NameServer | nameserver:9876 | localhost:9876 |
+| Broker-0 | broker-0:10911 | localhost:10911 |
+| Broker-1 | broker-1:10911 | localhost:10921(宿主机端口错开) |
+| Proxy remoting | proxy:8080 | localhost:8080 |
+| Proxy gRPC | proxy:8081 | localhost:8081 |
+
+注意:`brokerIP1=broker-{0,1}`,仅容器网络内客户端可直连 Broker。
+宿主机客户端直连需改为 `brokerIP1=127.0.0.1` 后重启对应 broker。
+
+## 清理
+
+```bash
+docker compose down -v
+```
diff --git a/deploy/rocketmq/build.sh b/deploy/rocketmq/build.sh
new file mode 100755
index 00000000..8112b03b
--- /dev/null
+++ b/deploy/rocketmq/build.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+# 构建 apache-rocketmq:develop 镜像
+# 自动判断地理位置:国内走阿里源(apt / Maven),国外用默认源
+set -e
+cd "$(dirname "$0")"
+
+country=$(curl -s --max-time 3 'http://ip-api.com/line?fields=countryCode' 
2>/dev/null || true)
+if [ -z "$country" ]; then
+    # 探测失败时用 google 可达性兜底:不可达视为国内
+    if curl -s --max-time 3 -o /dev/null https://www.google.com/generate_204 
2>/dev/null; then
+        country=OTHER
+    else
+        country=CN
+    fi
+fi
+
+if [ "$country" = "CN" ]; then
+    USE_CN_MIRROR=true
+else
+    USE_CN_MIRROR=false
+fi
+echo "geo=$country USE_CN_MIRROR=$USE_CN_MIRROR"
+
+USE_CN_MIRROR=$USE_CN_MIRROR docker compose build "$@"
diff --git a/deploy/rocketmq/clients/TraceConsumer.java 
b/deploy/rocketmq/clients/TraceConsumer.java
new file mode 100644
index 00000000..1a50e0d0
--- /dev/null
+++ b/deploy/rocketmq/clients/TraceConsumer.java
@@ -0,0 +1,24 @@
+import java.nio.charset.StandardCharsets;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import 
org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+
+public class TraceConsumer {
+    public static void main(String[] args) throws Exception {
+        String namesrv = System.getenv().getOrDefault("NAMESRV_ADDR", 
"nameserver:9876");
+        String topic = System.getenv().getOrDefault("TOPIC", "StudioTest");
+
+        // enableMsgTrace=true 开启消息轨迹,轨迹 topic 为 null 时使用默认 RMQ_SYS_TRACE_TOPIC
+        DefaultMQPushConsumer consumer = new 
DefaultMQPushConsumer("studio-trace-consumer", true, null);
+        consumer.setNamesrvAddr(namesrv);
+        consumer.subscribe(topic, "*");
+        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, 
ctx) -> {
+            msgs.forEach(m -> System.out.println(
+                "consume " + m.getMsgId() + " body=" + new String(m.getBody(), 
StandardCharsets.UTF_8)));
+            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+        });
+        consumer.start();
+        System.out.println("consumer started, topic=" + topic);
+        Thread.currentThread().join();
+    }
+}
diff --git a/deploy/rocketmq/clients/TraceProducer.java 
b/deploy/rocketmq/clients/TraceProducer.java
new file mode 100644
index 00000000..fe3f6d35
--- /dev/null
+++ b/deploy/rocketmq/clients/TraceProducer.java
@@ -0,0 +1,32 @@
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.common.message.Message;
+
+public class TraceProducer {
+    public static void main(String[] args) throws Exception {
+        String namesrv = System.getenv().getOrDefault("NAMESRV_ADDR", 
"nameserver:9876");
+        String topic = System.getenv().getOrDefault("TOPIC", "StudioTest");
+        long intervalMs = 
Long.parseLong(System.getenv().getOrDefault("SEND_INTERVAL_MS", "1000"));
+
+        // enableMsgTrace=true 开启消息轨迹,轨迹 topic 为 null 时使用默认 RMQ_SYS_TRACE_TOPIC
+        DefaultMQProducer producer = new 
DefaultMQProducer("studio-trace-producer", true, null);
+        producer.setNamesrvAddr(namesrv);
+        producer.start();
+        System.out.println("producer started, topic=" + topic + ", interval=" 
+ intervalMs + "ms");
+
+        long i = 0;
+        while (true) {
+            try {
+                Message msg = new Message(topic, "TagA", ("studio-msg-" + 
i).getBytes());
+                // 设置业务 Key,支持 queryMsgByKey 按 Key 检索
+                msg.setKeys("studio-key-" + i);
+                SendResult result = producer.send(msg);
+                System.out.println("send #" + i + " " + result.getSendStatus() 
+ " " + result.getMsgId() + " key=studio-key-" + i);
+            } catch (Exception e) {
+                System.out.println("send #" + i + " failed: " + 
e.getMessage());
+            }
+            i++;
+            Thread.sleep(intervalMs);
+        }
+    }
+}
diff --git a/deploy/rocketmq/conf/broker-0.conf 
b/deploy/rocketmq/conf/broker-0.conf
new file mode 100644
index 00000000..218ae6b5
--- /dev/null
+++ b/deploy/rocketmq/conf/broker-0.conf
@@ -0,0 +1,15 @@
+brokerClusterName=rocketmq-studio
+brokerName=rocketmq-studio-0
+brokerId=0
+brokerRole=ASYNC_MASTER
+flushDiskType=ASYNC_FLUSH
+deleteWhen=04
+fileReservedTime=48
+# 容器网络内通过服务名访问
+brokerIP1=broker-0
+namesrvAddr=nameserver:9876
+autoCreateTopicEnable=true
+autoCreateSubscriptionGroup=true
+# 消息轨迹:开启并自动创建轨迹 topic RMQ_SYS_TRACE_TOPIC
+traceOn=true
+traceTopicEnable=true
diff --git a/deploy/rocketmq/conf/broker-1.conf 
b/deploy/rocketmq/conf/broker-1.conf
new file mode 100644
index 00000000..b8afc2d6
--- /dev/null
+++ b/deploy/rocketmq/conf/broker-1.conf
@@ -0,0 +1,15 @@
+brokerClusterName=rocketmq-studio
+brokerName=rocketmq-studio-1
+brokerId=0
+brokerRole=ASYNC_MASTER
+flushDiskType=ASYNC_FLUSH
+deleteWhen=04
+fileReservedTime=48
+# 容器网络内通过服务名访问
+brokerIP1=broker-1
+namesrvAddr=nameserver:9876
+autoCreateTopicEnable=true
+autoCreateSubscriptionGroup=true
+# 消息轨迹:开启并自动创建轨迹 topic RMQ_SYS_TRACE_TOPIC
+traceOn=true
+traceTopicEnable=true
diff --git a/deploy/rocketmq/conf/rmq-proxy.json 
b/deploy/rocketmq/conf/rmq-proxy.json
new file mode 100644
index 00000000..f248dbf8
--- /dev/null
+++ b/deploy/rocketmq/conf/rmq-proxy.json
@@ -0,0 +1,7 @@
+{
+  "rocketMQClusterName": "rocketmq-studio",
+  "namesrvAddr": "nameserver:9876",
+  "remotingListenPort": 8080,
+  "grpcServerPort": 8081,
+  "enableTopicMessageTypeCheck": false
+}
diff --git a/deploy/rocketmq/docker-compose.yml 
b/deploy/rocketmq/docker-compose.yml
new file mode 100644
index 00000000..9e9a2f8a
--- /dev/null
+++ b/deploy/rocketmq/docker-compose.yml
@@ -0,0 +1,112 @@
+name: rocketmq
+
+services:
+  nameserver:
+    image: apache-rocketmq:develop
+    build:
+      context: .
+      args:
+        USE_CN_MIRROR: ${USE_CN_MIRROR:-false}
+    container_name: rmq-nameserver
+    command: sh bin/mqnamesrv
+    environment:
+      JAVA_OPT_EXT: -Xms512m -Xmx512m -Xmn256m
+    ports:
+      - "9876:9876"
+
+  broker-0:
+    image: apache-rocketmq:develop
+    container_name: rmq-broker-0
+    command: sh bin/mqbroker -c /etc/rocketmq/broker-0.conf
+    cpus: 1
+    mem_limit: 2g
+    environment:
+      NAMESRV_ADDR: nameserver:9876
+      JAVA_OPT_EXT: -Xms1g -Xmx1g -Xmn256m -XX:MaxDirectMemorySize=512m
+    volumes:
+      - ./conf/broker-0.conf:/etc/rocketmq/broker-0.conf:ro
+      - broker-0-store:/home/rocketmq/store
+      - broker-0-logs:/home/rocketmq/logs
+    ports:
+      - "10909:10909"
+      - "10911:10911"
+      - "10912:10912"
+    depends_on:
+      - nameserver
+
+  broker-1:
+    image: apache-rocketmq:develop
+    container_name: rmq-broker-1
+    command: sh bin/mqbroker -c /etc/rocketmq/broker-1.conf
+    cpus: 1
+    mem_limit: 2g
+    environment:
+      NAMESRV_ADDR: nameserver:9876
+      JAVA_OPT_EXT: -Xms1g -Xmx1g -Xmn256m -XX:MaxDirectMemorySize=512m
+    volumes:
+      - ./conf/broker-1.conf:/etc/rocketmq/broker-1.conf:ro
+      - broker-1-store:/home/rocketmq/store
+      - broker-1-logs:/home/rocketmq/logs
+    # 容器内仍监听 10911,宿主机端口错开避免冲突
+    ports:
+      - "10919:10909"
+      - "10921:10911"
+      - "10922:10912"
+    depends_on:
+      - nameserver
+
+  proxy:
+    image: apache-rocketmq:develop
+    container_name: rmq-proxy
+    command: sh bin/mqproxy -pc /etc/rocketmq/rmq-proxy.json
+    cpus: 1
+    mem_limit: 2g
+    environment:
+      JAVA_OPT_EXT: -Xms1g -Xmx1g -Xmn256m -XX:MaxDirectMemorySize=512m
+    volumes:
+      - ./conf/rmq-proxy.json:/etc/rocketmq/rmq-proxy.json:ro
+    ports:
+      - "8080:8080"
+      - "8081:8081"
+    depends_on:
+      - broker-0
+      - broker-1
+    restart: on-failure
+
+  producer:
+    image: apache-rocketmq:develop
+    container_name: rmq-producer
+    command: >
+      sh -c "javac -encoding UTF-8 -cp 'lib/*' -d /tmp/classes 
/clients/TraceProducer.java
+      && java -cp 'lib/*:/tmp/classes' TraceProducer"
+    environment:
+      # 指向 proxy remoting 端口,流量经 proxy 转发(proxy 会以自身地址应答路由)
+      NAMESRV_ADDR: proxy:8080
+      TOPIC: StudioTest
+      SEND_INTERVAL_MS: "1000"
+    volumes:
+      - ./clients:/clients:ro
+    depends_on:
+      - proxy
+    restart: on-failure
+
+  consumer:
+    image: apache-rocketmq:develop
+    container_name: rmq-consumer
+    command: >
+      sh -c "javac -encoding UTF-8 -cp 'lib/*' -d /tmp/classes 
/clients/TraceConsumer.java
+      && java -cp 'lib/*:/tmp/classes' TraceConsumer"
+    environment:
+      NAMESRV_ADDR: proxy:8080
+      TOPIC: StudioTest
+    volumes:
+      - ./clients:/clients:ro
+    depends_on:
+      - proxy
+    restart: on-failure
+
+volumes:
+  broker-0-store:
+  broker-0-logs:
+  broker-1-store:
+  broker-1-logs:

Reply via email to