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

Spring Boot Kafka 项目 Demo:订单事件系统 专家知识、源码阅读路线与面试题

Demo 目标

项目目录:

kafka-knowledge-system/demos/springboot-kafka-order-demo

这个 demo 模拟“订单服务发送订单事件,消费者处理并保存处理结果”的完整链路,覆盖生产项目最常见能力:

  • REST API 接收订单。
  • Producer 发送 Kafka 消息。
  • 使用orderId作为 key 保证同订单顺序。
  • Consumer 手动确认 offset。
  • 消费失败自动重试。
  • 重试失败后进入 DLT。
  • 消费端基于eventId做幂等。
  • 提供查询接口验证处理结果。

项目结构

springboot-kafka-order-demo ├── pom.xml ├── src/main/java/com/example/kafkaorder │ ├── KafkaOrderDemoApplication.java │ ├── config/KafkaConfig.java │ ├── controller/OrderController.java │ ├── event/OrderEvent.java │ ├── producer/OrderEventProducer.java │ ├── consumer/OrderEventConsumer.java │ └── service/OrderEventStore.java └── src/main/resources/application.yml

启动 Kafka

先启动 CLI demo 中的 Kafka:

cdkafka-knowledge-system/demos/cli-kafka-labdockercompose up-d

确认端口:

dockercomposeps

Kafka 对宿主机暴露localhost:9094,Spring Boot demo 默认连接这个地址。

启动项目

cdkafka-knowledge-system/demos/springboot-kafka-order-demo mvn spring-boot:run

如果首次运行 Maven 需要下载依赖,请保持网络可用。

发送正常订单事件

curl-XPOST http://localhost:8080/orders\-H'Content-Type: application/json'\-d'{"orderId":"O1001","userId":"U1","amount":99.80,"status":"CREATED"}'

预期返回:

{"eventId":"....","eventType":"ORDER_CREATED","orderId":"O1001","userId":"U1","amount":99.80,"status":"CREATED"}

查询处理结果:

curlhttp://localhost:8080/orders/O1001

预期能看到订单事件已被消费者处理。

触发失败和 DLT

发送一个状态为FAIL的事件:

curl-XPOST http://localhost:8080/orders\-H'Content-Type: application/json'\-d'{"orderId":"O9001","userId":"U9","amount":10.00,"status":"FAIL"}'

消费者会模拟业务异常,重试后进入 DLT:

dockercomposeexeckafka kafka-console-consumer\--bootstrap-server localhost:9092\--topicorder-events.DLT\--from-beginning\--timeout-ms5000

核心代码解释

Producer

OrderEventProducer发送消息时使用:

kafkaTemplate.send("order-events",event.orderId(),event)

这里的 key 是orderId,作用是让同一个订单的事件进入同一个 partition,保证单订单维度顺序。

Consumer

OrderEventConsumer使用手动确认:

store.handle(event);acknowledgment.acknowledge();

只有业务处理成功后才提交 offset。失败时抛出异常,交给 Spring Kafka 的错误处理器重试。

幂等

OrderEventStore使用eventId记录已处理事件。如果同一事件重复投递,消费者直接跳过,避免重复执行业务逻辑。

生产环境可以把这个逻辑落到数据库唯一键:

createtableprocessed_event(event_idvarchar(64)primarykey,processed_attimestampnotnull);

处理流程:

开始数据库事务 插入 processed_event(event_id) 如果唯一键冲突,说明已处理,直接返回 执行业务更新 提交事务 提交 Kafka offset

验证清单

验证项操作预期
Topic 自动创建启动应用order-events存在
Producer 正常POST/orders返回事件 JSON
Consumer 正常GET/orders/{id}能查到处理结果
Key 分区多发同一 orderId同订单顺序处理
重试status=FAIL日志出现重试
DLT消费最终失败order-events.DLT有消息
幂等重复 eventId不重复处理

项目扩展练习

  1. 增加订单支付事件ORDER_PAID
  2. 把内存存储替换为 MySQL。
  3. 使用 Outbox 表保证数据库订单和 Kafka 事件最终一致。
  4. 增加消息 Schema 版本字段兼容处理。
  5. 增加 Prometheus 指标:发送成功数、消费成功数、DLT 数、处理耗时。
  6. 增加 Testcontainers 集成测试。

专家级能力模型

Kafka 专家不是只会背 ISR、HW、ACK,而是能把业务目标、客户端配置、集群状态、监控指标和故障现场串起来。

能力具体表现
架构设计能设计 topic、partition、副本、Schema、权限和容量
可靠性治理能解释丢失、重复、乱序,并给出业务幂等方案
性能治理能从 producer、broker、consumer 三端定位瓶颈
运维治理能扩容、迁移、升级、故障演练
排障能力能通过 lag、ISR、请求延迟、磁盘指标定位问题
源码理解能理解 Controller、Coordinator、Replica、Log、Network

源码阅读路线

Kafka 源码可以按链路阅读,不建议从入口文件盲读。

第一阶段:请求链路

目标:理解 producer 请求到 broker 后怎么处理。

重点模块:

  • SocketServer
  • KafkaRequestHandler
  • KafkaApis
  • ReplicaManager
  • Partition
  • UnifiedLog

阅读问题:

  1. ProduceRequest 如何进入 broker?
  2. broker 如何找到 topic partition leader?
  3. 消息如何追加到日志?
  4. 什么时候返回成功?

第二阶段:复制链路

重点模块:

  • ReplicaFetcherThread
  • ReplicaManager
  • Partition
  • ISR 管理逻辑

阅读问题:

  1. follower 如何从 leader 拉取数据?
  2. ISR 什么时候扩大或缩小?
  3. HW 如何推进?
  4. leader 宕机后如何保证消费者不读到不稳定数据?

第三阶段:消费组

重点模块:

  • GroupCoordinator
  • ConsumerCoordinator
  • AbstractCoordinator
  • assignor 实现

阅读问题:

  1. 消费者如何加入 group?
  2. rebalance 如何触发?
  3. offset 存在哪里?
  4. static membership 如何减少 rebalance?

第四阶段:Controller 和元数据

重点模块:

  • KRaft Controller
  • metadata log
  • partition leader election

阅读问题:

  1. KRaft 如何替代 ZooKeeper?
  2. controller 负责哪些元数据变更?
  3. leader election 如何写入元数据日志?
  4. broker 如何感知元数据变化?

完整面试题与答案

1. Kafka 为什么吞吐高?

Kafka 高吞吐来自多个设计叠加:磁盘顺序追加写、OS page cache、批量发送、压缩、零拷贝、partition 并行、broker 横向扩展。顺序写避免随机 IO;page cache 让热点数据读写走内存;producer 将多条消息合批降低网络请求数;消费者批量拉取;partition 分布在多个 broker 上提高并行度。

追问:Kafka 是不是完全不依赖磁盘?

不是。Kafka 数据最终存储在磁盘日志中,只是大量读写会被 page cache 吸收。磁盘性能仍然决定长期稳定吞吐和恢复速度。

2. Topic、Partition、Offset 的关系是什么?

Topic 是消息分类,partition 是 topic 的物理分片,offset 是消息在某个 partition 内的递增位置。Kafka 只保证同一个 partition 内消息有序,不保证 topic 全局有序。消费者提交的是某个消费组在某个 topic-partition 上的 offset。

3. 为什么同一消费组内,一个 partition 不能被多个消费者同时消费?

因为 Kafka 用 partition 作为并行和顺序边界。如果同一个 partition 同时分给多个消费者,就无法保证 offset 提交和顺序处理的一致性。同一消费组内可以多个 partition 分给多个消费者,但一个 partition 同一时刻只分配给一个消费者。

4. Kafka 如何保证消息不丢?

需要三端配合:

  • Producer:acks=allenable.idempotence=true、合理重试。
  • Broker:核心 topic 使用 3 副本、min.insync.replicas=2、禁用 unclean leader election。
  • Consumer:业务处理成功后再提交 offset。

还要接受一个现实:业务端通常需要幂等,因为网络超时和重试会造成重复投递。

5. Kafka 会不会重复消费?

会。Kafka 常见语义是至少一次投递。比如消费者业务处理成功后,提交 offset 前宕机,重启后会重新消费同一条消息。解决方式是在业务层用eventId、业务唯一键、去重表或状态机做幂等。

6. 如何保证消息顺序?

把需要保证顺序的消息用同一个 key 发送到同一个 partition。例如同一订单的事件用orderId作为 key。Kafka 保证 partition 内顺序。消费者处理时也要避免对同一 partition 内消息并发乱序处理。

边界:如果需要全局顺序,只能使用一个 partition,但吞吐和并行度会下降。

7. ISR 是什么?

ISR 是 In-Sync Replicas,表示与 leader 保持同步的副本集合。Producer 使用acks=all时,leader 需要等待 ISR 中满足条件的副本确认后才返回成功。ISR 缩小说明副本复制跟不上,可能由 broker 宕机、网络抖动、磁盘慢或 GC 引起。

8. HW 和 LEO 的区别是什么?

LEO 是某个副本日志末尾 offset,代表该副本写到了哪里。HW 是消费者可见的最高安全 offset,代表 ISR 副本都确认到的位置。消费者只能读取 HW 之前的数据,避免读到 leader 写入但尚未复制、后来可能丢失的数据。

9.acks=all是否一定不丢消息?

不是。acks=all需要配合副本和 ISR 配置才有意义。如果 topic 只有一个副本,acks=all也只是等一个副本。生产环境应使用replication.factor=3min.insync.replicas=2,并禁用 unclean leader election。

10. 什么是 unclean leader election?

当 ISR 中没有可用副本时,Kafka 是否允许一个落后副本成为 leader。允许时可提高可用性,但可能丢失已确认消息;禁止时宁可 partition 暂时不可用,也不让落后副本成为 leader。核心业务通常禁用。

11. Consumer Lag 很高怎么排查?

先判断 lag 是持续增长还是短暂波峰。持续增长时按顺序排查:消费者是否报错、处理耗时是否增加、下游是否慢、消费者实例数是否不足、partition 是否不足、是否频繁 rebalance、是否某个 partition 热点。临时方案是扩容消费者、降低批处理耗时、启用 DLT、暂停非核心消费。

12. Rebalance 频繁的原因是什么?

常见原因:消费者处理时间超过max.poll.interval.ms、实例频繁发布或崩溃、心跳超时、topic partition 变化、消费组成员不稳定。治理方式:优化处理耗时、合理调大max.poll.interval.ms、使用 cooperative sticky assignor、静态成员 ID、优雅停机。

13. Kafka 事务解决什么问题?

Kafka 事务解决 Kafka 内部多条消息写入和 offset 提交的原子性。例如从 topic A 消费,处理后写 topic B,同时提交 A 的 offset,要么都成功,要么都不可见。它不能直接保证数据库和 Kafka 的跨系统强一致。

14. 数据库更新成功但 Kafka 发送失败怎么办?

推荐 Outbox 模式。业务事务中同时写业务表和 outbox_event 表。事务提交后,由后台任务或 CDC 读取 outbox 表发送 Kafka。发送成功后标记状态。这样避免“数据库成功但消息丢失”的不一致。

15. Kafka 如何做容量规划?

先收集峰值 TPS、平均消息大小、保留时间、副本数、压缩比、目标磁盘利用率。存储公式:

TPS * 消息大小 * 86400 * 保留天数 * 副本数 * 压缩比 / 磁盘目标利用率

再根据目标吞吐和消费者并行度估算 partition 数,并预留增长空间。

16. Partition 可以随便增加吗?

可以增加,但不能减少。增加 partition 会改变 key 到 partition 的映射,可能影响按 key 的顺序假设。增加过多还会增加文件句柄、元数据、controller、rebalance 和恢复成本。

17. Kafka 和 RabbitMQ 怎么选?

Kafka 更适合高吞吐、事件流、可回放、多订阅、日志采集和流计算。RabbitMQ 更适合传统任务队列、复杂路由、低到中等吞吐、每条消息投递语义更强的场景。选型要看业务是否需要保留事件流和回放能力。

18. 如何设计 Kafka 消费端幂等?

常见方式:

  • 事件表唯一键:event_id作为主键。
  • 业务状态机:订单已支付就不重复支付。
  • Redis set 去重:适合短期去重,但要处理过期和一致性。
  • 数据库唯一约束:最稳妥,适合核心业务。

核心原则:先判断是否处理过,再执行业务更新,并把判断和业务更新放在同一个事务边界内。

19. 如何处理毒丸消息?

毒丸消息是永远无法成功处理的消息,例如字段格式错误、业务状态非法。不能无限重试阻塞 partition。应该有限次重试,失败后进入 DLT,同时记录原因、topic、partition、offset、key、异常堆栈,后续人工修复或补偿。

20. Kafka 专家排障时最先看什么?

先看影响面:是 producer 写不进、consumer 堆积、broker 不健康,还是某个 topic 异常。然后看四组指标:consumer lag、under replicated partitions、request latency、磁盘/网络/CPU。不要只看应用日志,Kafka 问题通常需要客户端、broker 和下游系统一起看。

http://www.jsqmd.com/news/741875/

相关文章:

  • 3步掌握抖音内容高效下载:从零配置到批量保存的完整指南
  • .NET音视频处理利器:EIRTeam.FFmpeg封装库核心解析与实战
  • 模型驱动架构(MDA)在嵌入式开发中的应用与实践
  • ARM DBGTAP架构与调试技术深度解析
  • 别再手动拖拽UI了!Unity UGUI ContentSizeFitter组件搭配Layout Group的5个实战场景
  • D17: 项目估算:用 AI 提升准确度
  • 如何用DXVK让老旧Windows游戏在Linux上重获新生:终极性能提升指南
  • 手把手教你用STC15单片机驱动SHT30温湿度传感器(附完整代码和避坑指南)
  • 机器人软件测试:挑战、方法与实践
  • 2026年优秀COSTCO验厂咨询服务商盘点:GMP认证咨询、GRS认证咨询、HOMEDEPOT验厂咨询、ISCC认证咨询选择指南 - 优质品牌商家
  • Degrees of Lewdity中文汉化完整指南:从零开始轻松体验中文游戏
  • S32K312性能优化实战:手把手教你配置DTCM存放关键数据(附完整链接脚本修改)
  • OpenClaw与BotLearn:基于人机协同的学习操作系统实战指南
  • CefFlashBrowser:专业的Flash内容浏览器与游戏存档管理解决方案
  • 2026年质量优EPS装饰线条标杆名录:A级eps线条厂家/A级改性eps线条厂家/A级防火Eps线条/A级防火外墙Eps线条/选择指南 - 优质品牌商家
  • LLM工具调用优化:PORTool奖励树架构解析
  • 2026届最火的六大AI论文方案推荐榜单
  • 3步解锁闲鱼数据自动化:告别手动搜索的智能采集方案
  • 别再为el-cascader回显发愁了!一个key值+数组赋值的稳定方案(附自定义字段映射)
  • 惠州搬家服务排行:惠州工厂搬迁公司、惠州搬家公司电话、惠州搬家服务公司、惠州搬家电话、惠州搬迁公司、惠州蚂蚁搬家公司选择指南 - 优质品牌商家
  • LinkSwift:告别网盘限速的终极解决方案 - 八大平台直链下载助手完整指南
  • 代码评审实战指南:从原则到实践,打造高效协作文化
  • 华为光猫配置解密工具:5分钟掌握网络配置管理秘诀
  • RTOS中断优先级配置错误导致HardFault?2026主流芯片(STM32H753/ESP32-C6/NXP RT1180)配置模板全公开
  • CUDA 10.1编译报错?手把手教你Ubuntu下安装并切换gcc-7/g++-7(附镜像源配置)
  • Switch破解系统终极指南:为什么Atmosphere能成为最稳定的自定义固件
  • 从零开始掌握RoboMaster开发板:20个实战例程带你玩转STM32嵌入式开发
  • SSC-Scholar-Trader-Agent:基于NLP与知识图谱的量化交易智能体构建
  • 树莓派5 PCIe 3.0双M.2扩展板性能与应用解析
  • Cursor IDE多任务AI协作革命:基于MCP协议的侧边栏扩展实战