news 2026/9/25 20:03:43

Docker 部署 Kafka 消息中间件实战:Lottery 抽奖系统 MQ 环境搭建与生产消费验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker 部署 Kafka 消息中间件实战:Lottery 抽奖系统 MQ 环境搭建与生产消费验证
  • 文档
  • 教程
  • 后端

【免费下载链接】CodeGuide

:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、点赞、分享)!

项目地址:https://gitcode.com/gh_mirrors/code/CodeGuide
点击查看免费下载

本篇是 Lottery 分布式抽奖系统"系统运维"篇章的第 3 节实战指南。核心目标是在云服务器上借助 Docker 容器化技术安装并配置 Kafka 消息中间件(含其依赖的 Zookeeper),在 Kafka 后台为抽奖系统创建所需的 Topic 主题,并最终在本地程序中完成消息的生产与消费联调测试。读完本文,你将掌握从镜像拉取、容器启动、主题创建到 SpringBoot 程序验证的完整 Kafka 部署链路,并理解这套 MQ 环境如何在抽奖系统中承担"抽奖与发货流程解耦"的关键职责。

在 Lottery 抽奖系统(基于 DDD 领域驱动设计的四层架构实践)中,Kafka 是连接抽奖与发奖两个领域的关键纽带——抽奖完成后通过 MQ 异步触达奖品发货流程,避免流程过长导致用户长时间等待。本部署章节(与 Part-2 第 15、16 节的代码实现章节相互呼应)所搭建的 Kafka 环境,正是为了让这套 MQ 机制真正跑起来。文档原文见 第03节:部署环境 Kafka。

一、为什么抽奖系统需要 Kafka 消息中间件

在动手部署之前,先明确这套环境在项目中的定位。Lottery 项目的核心技术栈包含 SpringBoot、MyBatis、Dubbo、MQ、Redis、MySQL、ELK、分库分表等(见 Lottery 抽奖系统介绍),其中 MQ 选型在项目初期采用 Kafka,正如 第15节:搭建MQ消息组件Kafka服务环境 中所说明的:"MQ 消息的使用不非得局限于 Kafka,也可以使用 RocketMq",但 Kafka 本身具备非常突出的特性:

  • 可靠性:Kafka 是分布式、分区、复制且容错的,消息在集群内复制以防止数据丢失;
  • 可扩展性:消息系统可以轻松横向扩展且无需停机;
  • 耐用性:Kafka 使用分布式提交日志(commit log),消息会尽可能快地持久化到磁盘上;
  • 性能:对于消息的发布和订阅都具有高吞吐量,即使存储了大量消息也能保持稳定性能。

而 Kafka 在架构上构建在 Zookeeper 同步服务之上,因此部署 Kafka 必然要一并部署 Zookeeper——这也是本部署章节第一步先启动 Zookeeper 的原因。Zookeeper 在 Kafka 集群中承担 broker 注册发现、控制器(Controller)选举、Topic/分区元数据维护等协调职责。

在 Lottery 面试技能与问题汇总 中,针对"为什么使用 MQ 解耦发奖流程"给出了清晰的项目答案:把抽奖和发奖用 MQ 消息串联起来,避免一个流程太长,导致用户一直等待。这也正是本章节部署 Kafka 的最终业务价值所在。

二、下载 Kafka 与 Zookeeper 镜像

在 Docker 容器中安装 Kafka 的第一步是拉取镜像。原文档选用的是wurstmeister组织维护的 Kafka 与 Zookeeper 镜像,可以在 Docker Hub 官网镜像市场搜索对应镜像名称获取详细信息。

在云服务器终端执行如下两条命令,分别拉取 Kafka 与 Zookeeper 镜像:

docker pull wurstmeister/kafka docker pull wurstmeister/zookeeper

部署前提:本文以"云服务器 + Docker 容器"为部署环境。在 第01节:在云服务器部署 Docker 中已经完成了 Docker 的安装与 Portainer 运维面板的部署。如果你的服务器拉取 Docker Hub 镜像时报错(如error response from daemon: Get "https://registry-1.docker.io/v2/...),可以参考该节中配置registry-mirrors国内镜像加速的daemon.json写法后重启 Docker 再拉取。

命令参数说明:

参数含义
pull从 Docker Hub 拉取指定镜像到本地
wurstmeister/kafkaKafka 镜像,包含 Kafka Server 与配套脚本
wurstmeister/zookeeperZookeeper 镜像,用于支撑 Kafka 集群协调

三、启动 Zookeeper 容器

Kafka 依赖 Zookeeper 完成集群元数据管理,因此必须先于 Kafka 启动 Zookeeper。原文档给出的启动命令如下:

docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper

命令逐项拆解:

参数含义
-d以守护进程(后台)方式运行容器,容器日志可通过docker logs zookeeper或 Portainer 查看
--name zookeeper为容器命名,后续管理、停止、删除都可通过该名称操作
-p 2181:2181端口映射,将容器内 2181 端口映射到宿主机的 2181 端口,供 Kafka 与外部客户端访问
-t分配一个伪终端(TTY),便于查看交互式输出
wurstmeister/zookeeper使用的镜像名称

启动后,Zookeeper 的默认监听端口即为 2181(客户端连接端口)。由于后续 Kafka 容器需要与 Zookeeper 通信,且本地程序联调时也可能直接访问 Zookeeper,这个端口映射至关重要。

注意:如果容器间需要互相通信,Kafka 容器内访问 Zookeeper 既可以使用宿主机 IP(如192.168.x.x:2181),也可以让 Kafka 与 Zookeeper 处于同一 Docker 网络(--network)下通过容器名互访。云服务器部署场景下,为了让本地程序能够远程连接,还需要确保云厂商安全组中放行 2181、9092 等端口。

四、启动 Kafka 容器并完成配置

启动 Zookeeper 后,即可创建并启动 Kafka 容器。由于 Kafka 容器需要感知集群信息与外部访问地址,启动命令中需要注入关键环境变量:

docker run -d --name kafka \ -p 9092:9092 \ -e KAFKA_BROKER_ID=0 \ -e KAFKA_ZOOKEEPER_CONNECT=你的云服务器IP:2181 \ -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://你的云服务器IP:9092 \ -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \ wurstmeister/kafka

核心环境变量说明:

环境变量作用
KAFKA_BROKER_IDBroker 唯一标识,单机部署可设为 0
KAFKA_ZOOKEEPER_CONNECT指定 Kafka 连接的 Zookeeper 地址,指向上面启动的 Zookeeper 容器(宿主机 IP:2181)
KAFKA_ADVERTISED_LISTENERS对外公布的监听地址,必须配置为客户端(本地程序)能够访问到的 IP,否则本地程序会因拿到容器内部地址而连接失败
KAFKA_LISTENERSBroker 实际监听的地址,0.0.0.0:9092表示监听宿主机所有网卡的 9092 端口

启动完成后,可以通过 Portainer 运维面板直观地查看 kafka 容器的运行状态与日志,例如 Kafka 的 GroupCoordinator(消费者组协调器)会持续输出消费者组加入、退出等协调日志。下图展示了 Portainer 中 kafka 容器日志页面,日志中记录了抽奖系统lottery消费者组成员变化情况,这正是后续本地测试程序接入消费后的真实运行痕迹:

原文档以运维日志形式记录了这一部署环节:"在 Docker 容器中安装和配置 Kafka 环境"、"在 Kafka 后台添加抽奖系统需要的 Topic 主题,并在本地程序中进行测试"。部署到这一步,Kafka 环境已经具备承载 Topic 的能力。

五、在 Kafka 后台创建抽奖系统需要的 Topic

Kafka 中的消息以 Topic(主题)为单位组织,生产者向 Topic 写入消息,消费者从 Topic 拉取消息。抽奖系统需要为"发货单消息"创建专属主题。

在 第16节:使用MQ解耦抽奖发货流程 中明确说明:"启动 kafka 新增 topic:lottery_invoice 用于发货单消息,当抽奖完成后则发送一个发货单,再异步处理发货流程,这个部分就是 MQ 的解耦流程使用"。

对应 Topic 创建命令如下(本地 Kafka 安装包方式启动时的标准写法):

# 启动 Zookeeper(若使用本地安装包而非 Docker) bin/zookeeper-server-start.sh -daemon config/zookeeper.properties # 启动 Kafka bin/kafka-server-start.sh -daemon config/server.properties # 创建抽奖系统发货单主题 bin/kafka-topics.sh --create --zookeeper localhost:2181 \ --replication-factor 1 --partitions 1 --topic lottery_invoice

参数说明:

参数含义
--create创建新主题
--zookeeper localhost:2181指定 Zookeeper 地址,主题元数据由 Zookeeper 管理
--replication-factor 1副本因子为 1,单机部署时无需多副本
--partitions 1分区数为 1,单机场景下足以支撑抽奖系统的消息收发
--topic lottery_invoice主题名称,即抽奖发货单消息主题

如果 Kafka 运行在 Docker 容器中,也可以进入容器执行同样的脚本,例如:

docker exec -it kafka bin/kafka-topics.sh --create \ --zookeeper 你的云服务器IP:2181 \ --replication-factor 1 --partitions 1 --topic lottery_invoice

创建完成后,可通过bin/kafka-topics.sh --list --zookeeper localhost:2181验证主题是否已存在。

六、本地程序测试:SpringBoot 整合 Kafka 验证生产与消费

环境就绪后,需要在本地程序中完成消息的生产与消费联调验证。这一部分对应 第15节:搭建MQ消息组件Kafka服务环境 的分支211023_xfg_mq_kafka,其核心工作是:"搭建 Kafka 环境,配置消息主题"、"SpringBoot 整合 Kafka,验证消息的生产和消费"。

1. 配置生产者与消费者

在 SpringBoot 工程中引入 Kafka 依赖后,主要配置分为三块:

  • 生产者配置:bootstrap.servers指向你的云服务器IP:9092(即上文KAFKA_ADVERTISED_LISTENERS中公布的地址);key.serializer与value.serializer配置为StringSerializer,将消息对象序列化为字符串发送。
  • 消费者配置:同样指向bootstrap.servers,key.deserializer与value.deserializer配置为StringDeserializer;group.id指定消费者组,例如lottery(Portainer 日志中出现的lottery组即来源于此);enable.auto.commit决定是否自动提交消费位点。
  • Topic 确认:消费者监听lottery_invoice主题,收到发货单消息后进入发奖流程处理。

2. 验证消息生产与消费

本地程序启动后,向lottery_invoice主题发送一条消息,此时应能在消费者端日志中看到消息被成功接收。同时,在 Portainer 的 kafka 容器日志页面中,可以看到 GroupCoordinator 输出消费者组的加入与退出记录(如前面 3-02 截图所示),这是确认"本地程序已成功接入 Kafka 集群"的最直观证据。

常见联调问题与排查方向:

现象可能原因排查方向
生产/消费超时云服务器安全组未放行 9092 端口检查安全组入站规则
消费者连不上 BrokerADVERTISED_LISTENERS配成了容器内地址改为云服务器公网可达 IP
主题不存在未提前创建lottery_invoice按第五节命令创建主题

七、抽奖系统中的 MQ 应用:解耦抽奖与发货流程

Kafka 环境验证通过后,抽奖系统便真正具备了异步解耦能力。在 第16节:使用MQ解耦抽奖发货流程 中,这套机制在代码层面的落地点包括:

  1. 库表扩展:在数据库表user_strategy_export中添加字段mq_state,用于标记 MQ 消息是否发送成功——发送成功后更新库表状态;若发送失败,则通过定时任务补偿 MQ 消息,保证消息最终可达。
  2. 异步发货:在ActivityProcessImpl#doDrawProcess活动抽奖流程编排中,用户抽奖完成后发送 MQ 消息触达异步奖品发送流程,抽奖接口立即返回,用户无需等待发奖完成。
  3. 流程闭环:消费者收到lottery_invoice发货单消息后,进入奖品发放的处理链路,完成从抽奖到发奖的异步闭环。

这一设计与 Lottery 面试技能与问题汇总 中的项目问答相互印证:"解耦抽奖流程,把抽奖和发奖用 MQ 消息串联起来,避免一个流程太长,导致用户一直等待";同时面试中还会考察"消息丢失怎么办"——mq_state状态字段 + 定时任务补偿正是该项目给出的答案。

八、部署验证清单

完成本章节部署后,建议按以下清单逐项自检:

  1. docker ps中 zookeeper 与 kafka 两个容器均为 Up 状态;
  2. Portainer 容器列表可见两个容器,kafka 日志无 ERROR 级报错;
  3. kafka-topics.sh --list可列出lottery_invoice主题;
  4. 本地 SpringBoot 程序向lottery_invoice发送消息,消费者端与 Portainer 日志中均有消费记录;
  5. 云服务器安全组已放行 2181(Zookeeper)与 9092(Kafka)端口。

至此,Lottery 抽奖系统的 Kafka 消息中间件环境搭建完成,后续的 MQ 解耦发货流程、消息补偿等业务功能均可以在此基础上继续开发与联调。

  • 文档
  • 教程
  • 后端

【免费下载链接】CodeGuide

:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、点赞、分享)!

项目地址:https://gitcode.com/gh_mirrors/code/CodeGuide
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 20:00:23

RS485总线时通时断丢包严重?从硬件到软件的全链路排查实战手册

前阵子在化工厂调试仪表采集系统,23台压力、温度传感器走RS485总线串联,白天空载调试一切正常,一到晚上车间电机、变频器全开,就开始频繁丢包,有时候连续十几帧收不到回复,历史数据断得稀碎。 一开始下意识觉得是轮询逻辑写得有问题,熬了半宿改了三版调度算法,问题反而…

作者头像 李华
网站建设 2026/9/25 19:49:42

论文提质最快的方式,是从 GPT-6 的这六步修改法开始

各位同仁好,我是七哥。一个在高校里从事人工智能 相关领域研究,钻研用大模型AI实操的学术人。可以和七哥交流学术写作或Gemini、GPT、Claude 等大模型 学术实操相关问题,多多交流,相互成就,共同进步。 论文修改时,经常一个问题刚处理好,另一个问题又冒出来。 比如,…

作者头像 李华
网站建设 2026/9/25 19:47:59

AI 编程工具内存泄露与卡顿治理:大型代码库下的 IDE 优化配置

AI 编程工具内存泄露与卡顿治理:大型代码库下的 IDE 优化配置随着 AI 编程助手(Cursor、GitHub Copilot、Claude Code 等)在工程团队中成为每日标配,一个几乎所有深度用户都会遭遇的工程痛点随之而来: 在打开包含数十万…

作者头像 李华
网站建设 2026/9/25 19:43:09

Scanopy:不褪色的时序网络拓扑图谱系统

1. 这不是又一个“画图工具”,而是一套能自己长出血管的网络拓扑系统Scanopy 这个名字刚出来的时候,我第一反应是“扫描canopy(树冠)”——不是巧合。它真就像一棵活的树:根系扎进各个网段,枝干自动伸展&am…

作者头像 李华
网站建设 2026/9/25 19:33:39

AI 辅助功能的可解释性设计:PRD 中如何向用户呈现推理依据与参考源

AI 辅助功能的可解释性设计:PRD 中如何向用户呈现推理依据与参考源在 C 端娱乐场景中,AI 偶尔胡说八道可能只是一个有趣的段子;但在 B 端严肃商业场景(如合同合规审查、金融信贷审批、企业财务对账、医疗诊断辅助)中&a…

作者头像 李华