当前位置: 首页 > news >正文

使用 Docker 部署 Apache RocketMQ

这段内容是 《使用 Docker 部署 Apache RocketMQ》 的官方风格指南,它详细描述了如何通过 Docker 快速搭建一个单节点的 RocketMQ 服务(包含 NameServer、Broker 和 Proxy),并使用 Java SDK 发送和接收消息。

下面我将为你 逐段解析、翻译并深入解释其含义,帮助你彻底理解整个流程和背后的技术逻辑。


🐳 如何在 Docker 中运行 RocketMQ?(中文详解)

✅ 系统要求

  • 64 位操作系统(Linux / macOS / Windows)
  • 已安装 Docker 和 Docker Compose(推荐)

⚠️ 注意:虽然文档提到了 JDK 1.8+,但因为 RocketMQ 是用 Java 写的,而 Docker 镜像内部已经包含了 JRE,所以你不需要在宿主机上安装 JDK 来运行服务。但如果你要开发客户端程序(如 Java 项目),则需要本地有 JDK。


1️⃣ 拉取 RocketMQ 镜像

docker pull apache/rocketmq:5.3.2
🔍 解释:
  • 从 Docker Hub 下载官方发布的 RocketMQ 5.3.2 版本镜像。
  • 这个镜像是由 Apache 官方维护的,包含了完整的 RocketMQ 运行环境(JDK + RocketMQ 二进制文件)。
  • 使用 Docker 可以避免手动编译、配置等复杂步骤,非常适合快速测试和开发。

2️⃣ 创建 Docker 网络

docker network create rocketmq
🔍 解释:
  • Docker 默认容器之间不能直接通信,除非它们在同一个自定义网络中。
  • rocketmq 是我们创建的一个自定义桥接网络(bridge network),用于让 NameServerBroker 容器可以互相访问。
  • 后续启动容器时通过 --network rocketmq 加入该网络,就可以用容器名作为主机名进行通信(例如:rmqnamesrv:9876)。

✅ 类比:就像局域网内两台机器可以通过主机名访问一样。


3️⃣ 启动 NameServer(注册中心)

docker run -d \--name rmqnamesrv \-p 9876:9876 \--network rocketmq \apache/rocketmq:5.3.2 sh mqnamesrv
参数说明:
参数作用
-d后台运行容器
--name rmqnamesrv给容器命名,方便管理
-p 9876:9876将宿主机的 9876 端口映射到容器的 9876(NameServer 默认端口)
--network rocketmq加入自定义网络,便于与其他容器通信
sh mqnamesrv在容器中执行启动 NameServer 的命令
查看日志确认是否成功:
docker logs -f rmqnamesrv

✅ 成功标志:看到日志输出 The Name Server boot success...


4️⃣ 启动 Broker 和 Proxy(消息服务器)

(1)准备配置文件 broker.conf
echo "brokerIP1=127.0.0.1" > broker.conf
🔍 为什么需要这个?
  • 默认情况下,Broker 会用自己的内网 IP 地址注册到 NameServer。
  • 但在 Docker 中,容器的内网 IP 是虚拟的(如 172.x.x.x),宿主机无法直接访问。
  • 所以我们要强制 Broker 使用 127.0.0.1(即宿主机 loopback 地址)对外暴露,这样客户端才能从本机连接。

📌 这是 Docker 部署 RocketMQ 最关键的一步,否则客户端连不上!

(2)启动 Broker + Proxy 容器
docker run -d \--name rmqbroker \--network rocketmq \-p 10912:10912 -p 10911:10911 -p 10909:10909 \-p 8080:8080 -p 8081:8081 \-e "NAMESRV_ADDR=rmqnamesrv:9876" \-v ./broker.conf:/home/rocketmq/rocketmq-5.3.2/conf/broker.conf \apache/rocketmq:5.3.2 sh mqbroker --enable-proxy \-c /home/rocketmq/rocketmq-5.3.2/conf/broker.conf
参数详解:
参数说明
--name rmqbroker容器名称
--network rocketmq加入同一网络,可访问 rmqnamesrv
-p ...端口映射:
10911: Broker 控制端口
10912: Broker 数据端口
8081: Proxy gRPC 端口(客户端主要连接这里)
-e NAMESRV_ADDR=rmqnamesrv:9876设置环境变量,告诉 Broker 去哪个地址注册
-v ./broker.conf:/path/in/container挂载自定义配置文件进容器
sh mqbroker --enable-proxy启动 Broker 并启用 Proxy 模式(RocketMQ 5.x 新特性)
-c /path/to/broker.conf指定加载的配置文件
验证是否启动成功:
docker exec -it rmqbroker bash -c "tail -n 10 /home/rocketmq/logs/rocketmqlogs/proxy.log"

✅ 成功标志:看到日志中有 The broker[broker-a,127.0.0.1:10911] boot success...


✅ 当前架构总结

组件容器名访问方式用途
NameServerrmqnamesrvlocalhost:9876路由发现中心
Broker + Proxyrmqbrokerlocalhost:8081(Proxy)存储消息、处理收发请求

✅ 此时你已经部署了一个 单主模式的 RocketMQ 集群,可用于本地开发和测试。


5️⃣ 使用 SDK 发送和接收消息(Java 示例)

(1)添加依赖(Maven)
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>5.3.2</version>
</dependency>

💡 推荐版本与服务端一致(5.3.2),避免兼容性问题。

(2)进入容器创建 Topic
docker exec -it rmqbroker /bin/bash
./mqadmin updatetopic -t RequestTopic -c DefaultCluster

🔍 说明:

  • -t TestTopic:要创建的主题名
  • -c DefaultCluster:集群名(Docker 镜像默认配置)
  • 如果不创建 Topic,Broker 也可以自动创建,但建议显式创建以控制队列数量等参数。
(3)Producer 示例代码(发送消息)
package org.apache.rocketmq.example.rpc;import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;public class RequestProducer {public static void main(String[] args) throws MQClientException, InterruptedException {String producerGroup = "please_rename_unique_group_name";String topic = "RequestTopic";long ttl = 3000;DefaultMQProducer producer = new DefaultMQProducer(producerGroup);//You need to set namesrvAddr to the address of the local namesrvproducer.setNamesrvAddr("127.0.0.1:9876");producer.start();try {Message msg = new Message(topic,"","Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));long begin = System.currentTimeMillis();Message retMsg = producer.request(msg, ttl);long cost = System.currentTimeMillis() - begin;System.out.printf("request to <%s> cost: %d replyMessage: %s %n", topic, cost, retMsg);} catch (Exception e) {e.printStackTrace();}producer.shutdown();}
}
(4)Consumer 示例代码(接收消息)
package org.apache.rocketmq.example.rpc;import java.nio.charset.StandardCharsets;
import java.util.List;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.utils.MessageUtil;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.exception.RemotingException;public class ResponseConsumer {public static void main(String[] args) throws InterruptedException, MQClientException {String producerGroup = "please_rename_unique_group_name";String consumerGroup = "please_rename_unique_group_name";String topic = "RequestTopic";// create a producer to send reply messageDefaultMQProducer replyProducer = new DefaultMQProducer(producerGroup);replyProducer.setNamesrvAddr("127.0.0.1:9876");replyProducer.start();// create consumerDefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);consumer.setNamesrvAddr("127.0.0.1:9876");// recommend client configsconsumer.setPullTimeDelayMillsWhenException(0L);consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);for (MessageExt msg : msgs) {try {System.out.printf("handle message: %s %n", msg.toString());String replyTo = MessageUtil.getReplyToClient(msg);byte[] replyContent = "reply message contents.".getBytes(StandardCharsets.UTF_8);// create reply message with given util, do not create reply message by yourselfMessage replyMessage = MessageUtil.createReplyMessage(msg, replyContent);// send reply message with producerSendResult replyResult = replyProducer.send(replyMessage, 3000);System.out.printf("reply to %s , %s %n", replyTo, replyResult.toString());} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {e.printStackTrace();}}return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.subscribe(topic, "*");consumer.start();System.out.printf("Consumer Started.%n");}
}
🔍 关键点说明:
项目说明
NAMESRV_ADDR必须设置,查找服务端
ConsumerGroup必须指定,用于负载均衡和消费进度管理
FilterExpression("*", TAG)订阅所有标签的消息

6️⃣ 停止容器

# 停止 NameServer
docker stop rmqnamesrv# 停止 Broker
docker stop rmqbroker

✅ 也可以用 docker rm -f rmqnamesrv rmqbroker 一键删除容器。


🧠 总结:你该怎么理解这段文档?

步骤目的类比 Kafka
1. 拉取镜像获取可运行的 RocketMQ 环境下载 Kafka 镜像
2. 创建网络实现容器间通信自定义 Docker 网络
3. 启动 NameServer启动路由中心类似 ZooKeeper
4. 启动 Broker+Proxy启动消息服务器Kafka Broker
5. 挂载 broker.conf修复 IP 注册问题(关键!)配置 advertised.listeners
6. 使用 SDK实际开发集成方式使用 kafka-clients
7. 停止容器清理资源docker-compose down

✅ 实践建议(给初学者)

  1. 确保 Docker 正常运行

    docker --version
    docker run hello-world
    
  2. 检查端口占用

    • 9876 (NameServer)
    • 10911, 10912 (Broker)
    • 8081 (Proxy)
    • 若被占用,可修改 -p 映射端口。
  3. 日志查看技巧

    docker logs rmqnamesrv | grep success
    docker logs rmqbroker | grep boot
    
  4. 常见问题排查

    • 客户端连不上?→ 检查 broker.conf 是否设置了 brokerIP1=127.0.0.1
    • CONNECTION_TIMEOUT?→ 检查防火墙或端口映射
    • Topic 不存在?→ 使用 mqadmin updatetopic 创建
  5. 推荐使用 docker-compose.yml 简化部署(更优雅):

version: '3.8'
services:namesrv:image: apache/rocketmq:5.3.2container_name: rmqnamesrvports:- "9876:9876"command: sh mqnamesrvnetworks:- rocketmqbroker:image: apache/rocketmq:5.3.2container_name: rmqbrokerports:- "10911:10911"- "10912:10912"- "8081:8081"environment:- NAMESRV_ADDR=namesrv:9876volumes:- ./broker.conf:/home/rocketmq/rocketmq-5.3.2/conf/broker.confcommand: sh mqbroker --enable-proxy -c /home/rocketmq/rocketmq-5.3.2/conf/broker.confdepends_on:- namesrvnetworks:- rocketmqnetworks:rocketmq:driver: bridge

保存为 docker-compose.yml,然后运行:

# 启动
docker-compose up -d# 查看日志
docker-compose logs -f# 停止
docker-compose down

结论:这份文档教你如何用 Docker 快速搭建一个可用于开发测试的 RocketMQ 环境,比手动部署更简单、更干净。

需要我帮你写一个完整的 Spring Boot + RocketMQ 的 Docker 示例项目吗?欢迎继续提问!

http://www.dtcms.com/a/308317.html

相关文章:

  • 数据转换能干什么?有哪些好用的数据转换方法?
  • 剖析客户服务痛点,借助 Baklib 整合多渠道反馈
  • ADW300 物联网仪表:引领能源计量智能化变革
  • STM32标准库搭建示例(STM32F103C8T6)
  • 操作系统:上下文切换(Context Switch)
  • Effective C++ 条款13:以对象管理资源
  • LLC电源原边MOS管DS增加RC吸收对ZVS的影响分析
  • Linux和shell
  • 保姆级别IDEA关联数据库方式、在IDEA中进行数据库的可视化操作(包含图解过程)
  • ceph sc 设置文件系统格式化参数
  • 前端ESLint扩展的用法详解
  • 【实时Linux实战系列】实时图像处理应用开发
  • 【PHP类的基础概念:从零开始学面向对象】
  • Elasticsearch DSL 核心语法大全:match、bool、range、聚合查询实战解析
  • 使用神经网络与5折交叉验证进行基因组预测:基础知识指南
  • Java【代码 21】将word、excel文件转换为pdf格式和将pdf文档转换为image格式工具类分享(Gitee源码)aspose转换中文乱码问题处理
  • 智谱 AI 重磅发布 GLM-4.5:开源 SOTA,专为下一代智能体应用打造
  • 微服务架构技巧篇——接口类设计技巧
  • review|
  • Day15--二叉树--222. 完全二叉树的节点个数,110. 平衡二叉树,257. 二叉树的所有路径,404. 左叶子之和
  • 企业级部署 (基于tomcat与nginx)
  • 新书速览|R语言数据分析从入门到实践
  • Linux大页内存导致服务内存不足
  • Docker部署的PostgreSQL慢查询日志配置指南
  • 当文档包含图文混排表格时,如何结合大模型(如DeepSeek-VL)和OCR提取数据
  • 468. 验证IP地址
  • Ps2025
  • Python字典完全指南:从基础到实战(2025版)
  • 03 基于sklearn的机械学习-线性回归、损失函数及其推导
  • 大数据之Hive