Skip to main content

deploy-rocketmq

部署 RocketMQ Studio 与开源 RocketMQ。当用户说 部署 studio、把 studio 部署到远程机器/测试机、更新远程 studio、单机部署开源 rocketmq、远程部署 rocketmq 集群、单机部署 rocketmq 测试客户端、部署 studio 测试集群、部署负载挂具、给 K8s 集群上消费负载、制造消费延迟 inflight 时触发。

Quellinformationen

Repository
apache/rocketmq-dashboard
Letzte Quellaktivität
29. Oktober 2026 um 08:38
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
1.407
Forks
718

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
deploy-rocketmq
description
部署 RocketMQ Studio 与开源 RocketMQ。当用户说 部署 studio、把 studio 部署到远程机器/测试机、更新远程 studio、单机部署开源 rocketmq、远程部署 rocketmq 集群、单机部署 rocketmq 测试客户端、部署 studio 测试集群、部署负载挂具、给 K8s 集群上消费负载、制造消费延迟 inflight 时触发。
# 部署 RocketMQ Studio / 开源 RocketMQ 四种部署模式,全部遵循同一条主线: > **本地把源码打成 tar.gz → 复制到目标机器 → 在目标机器上构建镜像并启动。** > 构建统一在目标机执行,复用目标机本地缓存(Maven `~/.m2`、docker 层缓存), > 不做镜像中转。 | 模式 | 场景 | |------|------| | A. Studio 部署到目标机器 | 把本项目(server + web + mysql)部署到一台远程 Linux 机器,浏览器访问 | | B. 单机部署开源 RocketMQ | 在目标机器部署纯净开源集群(nameserver + 双 broker + proxy),不带测试挂具 | | C. 单机部署 RocketMQ 测试客户端 | 在目标机器部署模式 B 集群 + producer/consumer 1 TPS 轨迹挂具,供 Studio 调试 | | D. K8s 集群负载挂具 | 对 K8s 上的 RocketMQ 集群,用 docker compose 在同 VPC 机器跑单容器负载(4 种 topic 类型 × remoting/grpc 双协议消费 + 可控消费延迟),供 Studio 观测消费延迟/inflight | > ⚠️ 模式 A 可用 `deploy/deploy.sh` 一键执行;模式 B/C/D 无脚本,按手动步骤执行。 ## 通用前置条件(目标机器) - 已安装 `docker`(含 `docker compose`)。国内机器安装要点: - 用阿里源:`dnf config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo`; Alibaba Cloud Linux 3 需 `sed -i 's#$releasever#8#g' /etc/yum.repos.d/docker-ce.repo`(releasever=3 无对应目录)。 - 配 registry-mirrors(国内拉不动 Docker Hub,mysql:8.0 / dragonwell 等基础镜像必需), 写入 `/etc/docker/daemon.json` 的 `registry-mirrors`(如 `https://docker.m.daocloud.io` 等可用镜像站), 然后 `systemctl enable --now docker`。 - 用户已配置好到目标机的 SSH 密钥/证书访问(可免密登录;用 `ssh -o BatchMode=yes <user>@<host> whoami` 验证)。未配置时先与用户确认登录方式。 - 目标机器语言必须为 `en_US.UTF-8`:`export LANG=en_US.UTF-8`。SSH 会话内临时生效; 需持久化时追加到 `~/.bashrc` 或 `/etc/profile.d/`。用 `ssh <user>@<host> 'echo $LANG'` 验证。 - 放行所需端口:模式 A 放行 web 端口(默认 6789);模式 B/C 如需跨机访问放行 9876、10909、10911、10912、20909、20911、20912、8080、8081。 ### 测试集群可直接操作(用户授权 2026-10-14) 为验证 studio 功能,**测试环境(ECS + ACK `rocketmq1` 命名空间;地址一律从本地 `export` 的 `SSH_TARGET` / `STUDIO_URL` 环境变量取,仓库不存真实 IP)可以直接操作,无需先问**: 含改 broker 配置、重启 broker / Pod、重启 ECS 上的 `rmq-loadgen` 容器、开 ACL、建演示 topic/group 等 破坏性动作。前提是操作后**恢复原状**,或在 `rocketmq-studio-docs/progress/` 当日文档里记录留存状态。 生产/预发集群不在此授权内。 操作前必须知道的三个坑(2026-10-14 实测踩过): - **`rocketmq1` 的 broker store 是 emptyDir**(`broker-storage` volume 没有 PVC):**重启 broker Pod 会清空 全部消息与 topic / 订阅组配置**。重启后按 studio 元数据库的记录重建:`POST /api/topics/create`、 `POST /api/groups/create` 会把配置写回 broker;再重发演示消息、`docker restart rmq-loadgen`(ECS 上)、 重建集群内的演示消费者 Pod(裸 Pod 删了不会自愈,要重新 apply YAML)。 - **开 ACL 2.0(apache/rocketmq:5.5.0)的完整配方**:broker.conf 除 `authenticationEnabled=true`、 `authorizationEnabled=true` 外,还必须显式配 `authenticationProvider` / `authenticationMetadataProvider` / `authorizationProvider` / `authorizationMetadataProvider` 四个类名(该镜像默认为空,只开两个开关会报 `The authenticationMetadataProvider is not configured`,连 mqadmin 都建不了首个用户);并用 `initAuthenticationUser={"username":...,"password":...,"userType":"Super"}`(**User 对象的 JSON**)播种 首个 Super 账号。该账号要用 studio 的 admin 凭据同一对 AK/SK(在 ECS `/opt/rocketmq-studio/.env` 的 `SPRING_APPLICATION_JSON` → `studio.cluster.admin.credentials.<adminCredentialRef>`),否则开关一开 studio 自己的 admin 通道先被拒。验完把这几行删掉再重启即恢复。 - **broker ACL 2.0 的 resource 必须带类型前缀**:`Topic:<name>` / `Group:<name>`,集群域用 `*`。 裸名字会被解析成 null resource,整条账号写入报 `CODE: 16 The resource is null`。 --- ## 模式 A:部署 Studio 到目标机器 > 🚀 **一键脚本**:`deploy/deploy.sh [all|server|web]` 已实现本模式全流程 > (打包 → 传输 → 目标机构建 → compose 启动 → actuator/health 验证), > `deploy/.env` 配置 `REMOTE_HOST` 等。后续部署优先用脚本;以下手动步骤用于首次初始化与排障。 ### 核心原则 - **后端编译在目标机器上做**:复用目标机宿主机 `~/.m2/repository` 缓存,增量构建快。 - **国内目标机必须先检查 Maven 镜像源**(见步骤 2),否则依赖下载极慢或失败。 - 默认 `STUDIO_AUTH_LOGIN_REQUIRED=false` 免登录,方便直接查看效果;如需开启登录, 改为 `true` 并配好 admin 账号密码后重建 server。 ### 1. 初始化部署目录与 .env(仅首次) ```bash SSH="ssh <user>@<host>" $SSH bash -s <<'EOF' mkdir -p /opt/rocketmq-studio docker network inspect rocketmq_net >/dev/null 2>&1 || docker network create rocketmq_net cat > /opt/rocketmq-studio/.env <<'ENV' TZ=Asia/Shanghai MYSQL_ROOT_PASSWORD=rocketmq STUDIO_AUTH_LOGIN_REQUIRED=false STUDIO_AUTH_ADMIN_USERNAME=admin STUDIO_AUTH_ADMIN_PASSWORD=rocketmq RMQ_LLM_TOKEN= RMQ_ANTHROPIC_BASE_URL= ENV chmod 600 /opt/rocketmq-studio/.env EOF ``` - `MYSQL_ROOT_PASSWORD` 同时被 compose 用于 mysql 和 server 的 `SPRING_DATASOURCE_PASSWORD`,务必一致。 - compose 中 `rocketmq` 网络声明为 external(名 `rocketmq_net`),不存在时 `up` 会失败,必须先创建。 ### 2. 检查并配置 Maven 阿里源(国内目标机必做) 后端 JAR 用 maven 容器挂载宿主机 `~/.m2` 编译,镜像源配置来自宿主机 `~/.m2/settings.xml`。 先检查: ```bash $SSH 'grep -q "maven.aliyun.com" ~/.m2/settings.xml 2>/dev/null && echo OK || echo MISSING' ``` 输出 `MISSING` 时帮目标机写入(已有 settings.xml 则把 mirror 合并进 `<mirrors>`,不要整文件覆盖): ```bash $SSH 'mkdir -p ~/.m2 && cat > ~/.m2/settings.xml <<'"'"'XML'"'"' <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"> <mirrors> <mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror> </mirrors> </settings> XML' ``` ### 3. 本地打包源码并复制到目标机 ```bash cd <项目根目录> # rocketmq-studio 仓库根 # rmqctl, LICENSE and NOTICE have to travel with the package: the server image is built with the # repository root as its context, and the rmqctl stage of server/Dockerfile copies all three. # deploy/.env is per-environment and rmqctl/bin is a local build artifact, so both stay out. tar czf /tmp/src.tar.gz \ --exclude='web/node_modules' --exclude='web/dist' --exclude='server/target' \ --exclude='deploy/.env' --exclude='rmqctl/bin' \ LICENSE NOTICE server web deploy rmqctl scp /tmp/src.tar.gz <user>@<host>:/opt/rocketmq-studio/ $SSH 'cd /opt/rocketmq-studio && rm -rf server web deploy rmqctl LICENSE NOTICE && tar xzf src.tar.gz && rm src.tar.gz' ``` ### 4. 在目标机上编译后端 + 构建镜像 复用宿主机 `~/.m2` 缓存编译 JAR,再用 Dockerfile 的 `runtime-prebuilt` target 打镜像 (不要走默认多阶段 build target,那会在 Docker 内从零下载依赖、用不上宿主机缓存)。 **构建上下文是仓库根目录而不是 `server/`**:Dockerfile 的 rmqctl 阶段要 `COPY rmqctl/` 与根目录的 `LICENSE NOTICE`,镜像才会自带 `/usr/local/bin/rmqctl`(AI 后端以 `rmqctl mcp stdio` 拉起 MCP server): ```bash $SSH 'cd /opt/rocketmq-studio && \ docker run --rm -e HOME=/tmp \ -v $PWD/server:/app -v $HOME/.m2:/maven-cache -w /app \ maven:3.9.16-eclipse-temurin-21 \ mvn -B -ntp -s /maven-cache/settings.xml -Dmaven.repo.local=/maven-cache/repository package -DskipTests && \ docker build --target runtime-prebuilt -f server/Dockerfile -t rocketmq-server:latest .' ``` - 若目标机 `~/.m2/settings.xml` 不存在(海外机器通常不需要镜像源),去掉 `-s /maven-cache/settings.xml`。 - maven 基础镜像本身也要拉取,国内依赖通用前置条件里的 registry-mirrors。 构建 web(页脚「构建 <短commit>」由 `VITE_GIT_COMMIT` 注入,先取当前 git 短 commit): ```bash $SSH 'cd /opt/rocketmq-studio && \ docker build --build-arg VITE_GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo dev) -t rocketmq-web:latest web/' ``` ### 5. 启动与验证 ```bash $SSH 'cd /opt/rocketmq-studio && docker compose --env-file .env -f deploy/docker-compose.yml up -d' # 三容器均 healthy 即成功 $SSH 'docker ps' $SSH 'docker exec rocketmq-server curl -fsS http://localhost:8888/actuator/health' curl -s -o /dev/null -w 'web %{http_code}\n' http://<host>:6789/ ``` ### 6. 更新代码后重新部署 重复步骤 3 → 5 即可。注意: - mysql 数据在独立数据卷 `mysql-data`,重建 server/web 不影响数据;**不要 `down -v`**。 - 仅改 server 时只需重编 server(步骤 4 前半段)并 `docker compose ... up -d rocketmq-server`。 ### 可选:注入演示数据 `deploy/mysql/upgrade-demo-instance.sql` / `upgrade-demo-acl.sql` 可注入演示实例/ACL。 导入后必须补 vendor,否则 `/api/instances` 报 500(demo SQL 早于 vendor 功能): ```bash $SSH 'docker exec rocketmq-studio-mysql mysql -uroot -procketmq rocketmq \ -e "UPDATE rmq_instance SET vendor=\"APACHE\" WHERE vendor IS NULL OR vendor=\"\";"' ``` --- ## 模式 B:单机部署开源 RocketMQ(纯净集群) 在目标机器部署一套开源 RocketMQ 集群(NameServer + 双 Broker + Proxy,集群名 `rocketmq-studio`,Broker 开启消息轨迹),不带 producer/consumer 测试挂具, 供任意客户端或 Studio 接入。部署产物在仓库 `deploy/rocketmq/` 目录。 ### 1. 本地打包并复制到目标机 ```bash SSH="ssh <user>@<host>" tar czf /tmp/rocketmq-deploy.tar.gz -C deploy rocketmq scp /tmp/rocketmq-deploy.tar.gz <user>@<host>:/tmp/ $SSH 'mkdir -p /opt/rocketmq && rm -rf /opt/rocketmq/rocketmq && \ tar xzf /tmp/rocketmq-deploy.tar.gz -C /opt/rocketmq && rm /tmp/rocketmq-deploy.tar.gz' ``` ### 2. 在目标机上构建镜像 ```bash $SSH 'cd /opt/rocketmq/rocketmq && ./build.sh' ``` - `build.sh` 自动判断地理位置:国内切阿里 apt/Maven 源,国外用默认源。 - Dockerfile 为多阶段构建:builder 阶段 `git clone --depth 1 -b rocketmq-all-5.5.0 https://github.com/apache/rocketmq.git` 后执行 `mvn -Prelease-all -DskipTests clean install`,运行阶段仅保留 `bin/ conf/ lib/` 产物,基础镜像 `alibabadragonwell/dragonwell:17-anolis`(yum 系,国内拉取快)。 - 构建阶段需访问 github.com,国内机器若 clone 慢或失败,用 `--build-arg ROCKETMQ_REPO=<镜像仓库地址>` 换源。 - 首次构建需 10-20 分钟;默认钉已发布 tag(与 `server/pom.xml` 的 `rocketmq.version` 对齐), 换版本用 `./build.sh --build-arg ROCKETMQ_BRANCH=rocketmq-all-5.5.1` 并同步改 `docker-compose.yml` 的 image tag;跟未发布分支用 `ROCKETMQ_BRANCH=develop`(仅限本地排查, 不要把 develop 钉回仓库)。 ### 3. 启动(仅核心服务) ```bash $SSH 'docker network inspect rocketmq_net >/dev/null 2>&1 || docker network create rocketmq_net' $SSH 'cd /opt/rocketmq/rocketmq && docker compose up -d nameserver broker-0 broker-1 proxy' ``` - broker-0 监听 10909/10911/10912,broker-1 在 broker-1.conf 里通过 `listenPort=20911` 直接监听 20909/20911/20912(fast/ha 端口自动 -2/+1),容器与宿主机端口 1:1 映射。 - 堆内存通过 `JAVA_OPT_EXT` 环境变量收敛(开源启动脚本会将其追加到 JVM 参数末尾, 覆盖脚本内置的大堆默认值),适合小内存环境。 ### 4. 验证 ```bash $SSH 'cd /opt/rocketmq/rocketmq && docker compose ps' $SSH 'cd /opt/rocketmq/rocketmq && \ docker compose exec -T nameserver sh bin/mqadmin clusterList -n nameserver:9876' ``` 通过标准:clusterList 能看到 `rocketmq-studio` 集群下 `rocketmq-studio-0`、 `rocketmq-studio-1` 两个 broker,且 `#ACTIVATED=true`。 ### 5. 网络接入说明 - **与 Studio 同机部署**:两边共用 `rocketmq_net` 网络,Studio server 容器直接用 `nameserver:9876` 接入(compose 默认 `STUDIO_ROCKETMQ_NAMESRV_ADDR=nameserver:9876`)。 - **跨机访问**:`brokerIP1=broker-{0,1}` 仅容器网络内可达,宿主机/其他机器直连需改 `conf/broker-{0,1}.conf` 为 `brokerIP1=<目标机器 IP>` 并重启 broker,同时放行 9876、10909、10911、10912、20909、20911、20912、8080、8081。 - proxy 对外提供 remoting 8080 / gRPC 8081 接入点,已关闭 topic 消息类型校验 (`enableTopicMessageTypeCheck=false`,避免自动建 topic 类型为 UNSPECIFIED 时发送被拒)。 --- ## 模式 C:单机部署 RocketMQ 测试客户端 在目标机器部署模式 B 的集群,并额外拉起 Producer / Consumer 容器以 1 TPS 持续 收发消息并上报轨迹,供 RocketMQ Studio 调试使用。 ### 1. 准备与构建 同模式 B 步骤 1 → 3,但启动全部服务(含 producer/consumer): ```bash $SSH 'cd /opt/rocketmq/rocketmq && docker compose up -d' ``` producer / consumer 服务说明(容器名均带 `rmq-` 前缀): | 服务 | 说明 | |------|------| | producer | 编译并运行 `clients/TraceProducer.java`,1 TPS 发送到 `StudioTest`(带 Key `studio-key-<n>`),`enableMsgTrace=true`,直连 `nameserver:9876` | | consumer | 编译并运行 `clients/TraceConsumer.java`,Push 消费 `StudioTest`,`enableMsgTrace=true`,直连 `nameserver:9876` | producer / consumer 直接用运行镜像自带 JDK + `lib/*` 依赖现场编译,无需额外构建。 ### 2. 验证 ```bash # 收发日志:producer 每秒一条 SEND_OK,consumer 对应 consume $SSH 'docker logs -f --tail 50 rmq-producer' # 消息轨迹已落盘(RMQ_SYS_TRACE_TOPIC 有数据即轨迹链路打通) $SSH 'cd /opt/rocketmq/rocketmq && docker compose exec -T broker-0 \ sh bin/mqadmin consumeMessage -n nameserver:9876 -t RMQ_SYS_TRACE_TOPIC -c 5' ``` 验证通过标准:模式 B 的 clusterList 标准之外,producer 日志持续输出 `SEND_OK`; `RMQ_SYS_TRACE_TOPIC` 能消费出轨迹数据。 ### 3. 清理 ```bash $SSH 'cd /opt/rocketmq/rocketmq && docker compose down -v' ``` --- ## 模式 D:K8s 集群负载挂具(4 种 topic 类型 × 双协议消费) 对部署在 K8s 上的 RocketMQ 集群(如社区 Helm chart 部署的 rocketmq1/rocketmq2), 在与集群**同 VPC** 的机器上用 docker compose 跑一个负载容器: - producer 每秒向 4 种类型 topic(NORMAL / FIFO / DELAY / TRANSACTION)各发 1 条 - 每个 topic 挂 1 个 remoting push 消费者 + 1 个 gRPC simple 消费者,共 **8 个消费者** - 每条消息消费时固定 sleep `CONSUME_DELAY_MS`(默认 15s)才返回 success, 使管控(Studio)能看到稳定的消费延迟与 inflight(稳态积压 ≈ TPS × 延迟秒数/组) 源码在 terrances 仓库 `project/rocketmq-loadgen/`(不放进 apache 仓库), 本地 `mvn package` 出 fat jar 后传到目标机器构建镜像。 ### 1. 为 proxy 创建内网 SLB(关键知识点) 社区 Helm chart 的 Service 全部硬编码 headless(`clusterIP: None`),集群外机器 只能直连 Pod IP,而 **Pod IP 在 pod 重建后会变**。稳定做法是给 proxy 建一个 **内网 SLB**(LoadBalancer Service): ```yaml apiVersion: v1 kind: Service metadata: name: <release>-proxy-slb # 如 rocketmq1-proxy-slb namespace: <namespace> annotations: # 强制内网 SLB,禁止公网暴露(测试集群纪律:No public SLB) service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "intranet" spec: type: LoadBalancer selector: # 与 chart proxy Service 的 selector 一致 app.kubernetes.io/instance: <release> app.kubernetes.io/name: proxy ports: - { name: remoting, port: 8080, targetPort: 8080, protocol: TCP } - { name: grpc, port: 8081, targetPort: 8081, protocol: TCP } ``` ```bash kubectl apply -f proxy-slb.yaml # 等待 EXTERNAL-IP 分配(约 10~30s) kubectl -n <ns> get svc <release>-proxy-slb -w
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen