高并发 Spring Boot 微服务工程骨架:从 Maven 多模块、领域分层到 Redis + Kafka 秒杀与 Kubernetes 部署
高并发 Spring Boot 微服务工程骨架:从 Maven 多模块、领域分层到 Redis + Kafka 秒杀与 Kubernetes 部署本文不是 Spring Boot 的入门教程,也不是把 Controller、Service、Mapper 分成三个包就称为“架构设计”。我们将围绕一个真实的高并发秒杀场景,从版本选型、Maven 多模块、依赖方向、领域建模、Redis 原子受理、Redis Stream 可靠中转、Kafka 消息投递、数据库幂等、失败补偿、Nacos 配置、容器镜像、Kubernetes 部署、可观测性与压测验收等方面,搭建一套可直接迁移到生产项目的工程骨架。目录1. 为什么高并发系统首先要治理工程结构2. 业务场景与容量目标3. 总体架构与请求链路4. 技术版本与兼容性策略5. Maven 多模块工程设计6. 包结构与依赖方向7. 父 POM 与版本治理8. 领域模型与订单状态机9. 数据库表与唯一约束10. 秒杀受理链路设计11. Redis Lua 原子受理12. Redis Stream 到 Kafka 的可靠中转13. Kafka 生产端可靠性配置14. Kafka 消费端幂等与事务15. Controller、应用服务与异常体系16. Nacos 注册与配置管理17. 虚拟线程的正确使用方式18. 容器镜像构建19. Kubernetes 生产部署20. 可观测性与告警指标21. 压测方法与验收标准22. 常见生产事故与处理策略23. 架构演进路线24. 上线检查清单25. 总结附录 A:核心配置样例附录 B:本地开发环境参考资料1. 为什么高并发系统首先要治理工程结构很多团队第一次面对流量增长时,会优先讨论 Redis、MQ、分库分表和 Kubernetes,却忽略了一个更基础的问题:工程结构是否允许系统持续演进。当项目只有几个接口时,把代码放在controller、service、mapper三个目录中并不会立即出问题。但随着业务增加,通常会逐渐出现以下现象:OrderServiceImpl超过数千行,既做参数校验,又编排业务,还直接操作 Redis、Kafka 和数据库。Controller 依赖数据库实体,外部接口字段变化直接影响持久化模型。领域规则散落在 SQL、Service 和消息消费者中,同一条规则被重复实现。Kafka 消费者直接调用 Mapper,绕过业务校验和状态机。公共模块不断膨胀,最终变成任何服务都能依赖的“万能工具箱”。服务虽然部署在 Kubernetes 中,但没有优雅停机、探针、资源边界和流量摘除机制。发生消息重复、Redis 扣减成功但消息未发送、数据库落单失败时,没有明确的恢复路径。高并发系统的复杂性并不只来自 QPS,还来自并发状态、跨组件失败、重复执行、异步延迟和持续迭代。工程骨架的目标,是让这些复杂性有明确的归属,而不是被堆进一个 Service 方法。本文遵循以下原则:接口层负责协议适配,不承载核心业务规则。应用层负责编排用例,不直接依赖具体中间件客户端。领域层表达业务状态、约束和行为。基础设施层实现数据库、Redis、Kafka、Nacos 等技术细节。跨系统链路默认采用“至少一次投递 + 幂等消费 + 可补偿对账”,而不是假设网络永远可靠。所有关键状态都必须可查询、可追踪、可重放。2. 业务场景与容量目标假设“闪电购”是一套电商秒杀系统,核心链路如下:用户点击立即抢购 ↓ 网关鉴权、限流、防刷 ↓ 订单服务校验活动与用户资格 ↓ Redis 原子校验并预扣库存 ↓ 写入 Redis Stream 受理事件 ↓ 中转任务发送 Kafka ↓ 订单消费者幂等落库 ↓ 返回订单查询状态 ↓ 支付、履约、积分等后续事件2.1 业务约束同一用户对同一活动商品最多成功购买一次。库存不能超卖。接口重试不能重复扣减库存。消息重复投递不能重复创建订单。Redis、Kafka 或数据库短暂故障后,链路能够恢复。系统发布、Pod 驱逐或扩缩容时,不能随意中断正在处理的消息。用户收到“排队中”后,必须能够查询最终结果。2.2 容量目标示例下表是设计输入,不代表本文代码已经完成对应压测。实际项目必须根据业务规模重新测量。指标设计目标示例商品详情峰值 QPS30,000秒杀受理峰值 QPS8,000单活动瞬时并发20,000受理接口 P99小于 100 msRedis 受理成功到 Kafka 可见 P99小于 1 sKafka 到数据库落单 P99小于 3 s重复订单数0超卖数量0消息最终可恢复率100%容量指标必须区分三个概念:受理能力:系统能否快速接受请求并返回排队结果。消化能力:Kafka 消费端每秒能够稳定落多少订单。恢复能力:组件故障后积压多久能够追平。仅看接口 QPS,而不看消息积压和数据库消化速度,会得到错误的容量结论。3. 总体架构与请求链路3.1 逻辑架构用户端CDN / WAFSpring Cloud GatewayOrder ServiceNacos 注册与配置Redis ClusterRedis StreamStream RelayKafka ClusterOrder ConsumerMySQL / PostgreSQLPrometheus / OpenTelemetry3.2 为什么不直接“Redis 扣库存后发送 Kafka”最常见的实现是:Redis DECR 成功 ↓ 调用 KafkaTemplate.send()这段逻辑存在跨系统原子性问题:Redis 已扣减,应用在发送 Kafka 前宕机,库存被占用但订单事件丢失。Kafka 实际发送成功,但客户端等待结果超时,应用误以为失败并回补库存,可能造成库存与订单不一致。发送失败后立即回补库存,如果回补也失败,就需要额外恢复机制。本文采用以下方式缩小故障窗口:在同一个 Redis Lua 脚本中完成资格校验、库存预扣、幂等标记和XADD。独立 Relay 从 Redis Stream 读取受理事件并发送 Kafka。Kafka 发送成功后再XACK。Relay 崩溃导致事件重复发送时,下游通过业务键和数据库唯一约束幂等处理。Redis Stream 待确认列表、Kafka 消费积压和数据库状态均纳入监控。这不是分布式强事务,而是一套可恢复的至少一次处理链路。3.3 失败语义位置可能失败处理方式网关到订单服务超时、重试请求携带requestId,受理脚本幂等Redis LuaRedis 不可用快速失败,不进入数据库兜底抢库存Stream Relay进程宕机Consumer Group 的 Pending 消息重新认领Relay 到 Kafka超时或重试Kafka 幂等生产者,下游继续幂等Kafka Consumer重复投递Inbox 表或业务唯一键去重数据库事务死锁、超时有界重试,失败进入重试主题或暂停分区订单创建后续事件发送失败Transactional Outbox 可靠发布4. 技术版本与兼容性策略4.1 不要把“最新版本”直接等同于“生产基线”截至 2026 年 7 月,Spring Boot 官方项目页已经展示 4.1.x,Spring Cloud 2025.1.2 支持 Spring Boot 4.0.x,并从 2025.1.2 开始支持 4.1.x。但 Spring Cloud Alibaba 的稳定发行节奏可能与 Spring Boot、Spring Cloud 不完全同步。因此,本文示例采用以下原则:核心框架选择已有正式兼容组合。Kafka Broker 可以使用当前维护版本,但 Java 客户端优先由 Spring Boot BOM 管理。不在父 POM 中随意覆盖 Spring Kafka、Jackson、Netty 等传递依赖版本。每次升级先通过兼容矩阵、集成测试和压测,再进入生产。4.2 本文建议基线组件示例基线说明JDKJava 21 LTS虚拟线程正式可用,生态成熟Spring Boot4.0.0与示例 SCA 正式版本对应Spring Cloud2025.1.0与 SCA 2025.1.0.0 对应Spring Cloud Alibaba2025.1.0.0正式支持 Spring Boot 4.0 与 Cloud 2025.1.0Nacos Client由 SCA BOM 管理避免手工覆盖客户端版本MyBatis-Plus3.5.13 或更高兼容版3.5.13 起提供 Spring Boot 4 适配说明Kafka Broker4.3.xBroker 与客户端需按兼容文档验证Redis / Valkey企业当前维护版本要求持久化、主从和故障转移Maven3.9.x配合 Toolchains 固定 JDK若团队暂不计划升级 Spring Boot 4,可采用 Java 21 + Spring Boot 3.5.x + Spring Cloud 2025.0.x + Spring Cloud Alibaba 2025.0.0.0。生产项目不应只复制本文版本号,而应锁定经过组织验证的版本基线。4.3 版本治理规则Spring Boot、Spring Cloud、Spring Cloud Alibaba 使用 BOM 管理。只有 BOM 未覆盖且确实需要的库才在properties中声明版本。禁止业务模块直接覆盖 Jackson、Netty、Tomcat、Spring Kafka 等核心组件版本。CI 中执行mvn dependency:tree和依赖漏洞扫描。升级采用独立分支,先完成编译、单测、容器启动、契约测试、故障测试和性能回归。5. Maven 多模块工程设计5.1 推荐目录lightning-order/ ├── pom.xml ├── order-contract/ # 对外契约:请求、响应、Feign 契约、事件协议 ├── order-domain/ # 领域模型:聚合、值对象、领域服务、仓储接口 ├── order-application/ # 应用用例:命令、查询、事务编排 ├── order-infrastructure/ # DB、Redis、Kafka、Nacos 等技术实现 ├── order-interfaces/ # HTTP Controller、Kafka Listener、定时入口 ├── order-bootstrap/ # Spring Boot 启动、装配、配置 ├── order-test-support/ # Testcontainers、测试数据工厂 ├── deploy/ │ ├── docker/ │ └── kubernetes/ └── docs/5.2 各模块职责order-contract用于跨进程共享的稳定契约:HTTP 请求与响应 DTO。OpenFeign 接口。Kafka 事件 Schema。错误码定义。该模块不能依赖数据库实体、Mapper 或 Spring Boot 启动模块。order-domain领域层只表达业务:Order聚合根。OrderStatus状态机。Money、OrderId、ActivityId等值对象。OrderRepository仓储接口。领域事件。领域层不应该知道 MyBatis、RedisTemplate、KafkaTemplate 和 HTTP。order-application应用层表达用例:秒杀受理。订单查询。创建订单。取消订单。支付结果处理。它负责事务边界和流程编排,但通过端口接口访问外部系统。order-infrastructure基础设施层实现端口:MyBatis-Plus Repository。Redis Lua 与 Stream。Kafka Producer。Nacos 配置适配。分布式 ID、时钟、序列化等实现。order-interfaces接口层承接不同协议:REST Controller。Kafka Listener。定时任务入口。管理接口。接口层将协议对象转换为应用命令,不直接写核心业务逻辑。order-bootstrap唯一可执行模块:OrderApplication。Spring Bean 装配。application.yml。Actuator、线程模型、序列化等全局配置。5.3 模块依赖方向order-contractorder-domainorder-applicationorder-infrastructureorder-interfacesorder-bootstrap关键约束是:domain不能依赖infrastructure。application依赖抽象端口,不依赖具体客户端。bootstrap负责把接口和实现装配起来。不创建一个所有模块都能随意依赖的巨大common模块。6. 包结构与依赖方向以com.lightning.order为根包:com.lightning.order ├── contract │ ├── api │ ├── command │ ├── response │ └── event ├── domain │ ├── model │ ├── repository │ ├── service │ └── event ├── application │ ├── port │ │ ├── in │ │ └── out │ ├── command │ ├── query │ └── service ├── infrastructure │ ├── persistence │ ├── redis │ ├── messaging │ ├── config │ └── id ├── interfaces │ ├── rest │ ├── consumer │ ├── scheduler │ └── admin └── bootstrap └── OrderApplication6.1 垂直切分与水平切分如何选择小型服务可以按技术层水平切分。业务继续增长后,更推荐在每个业务域内垂直组织:order/ ├── seckill/ │ ├── application/ │ ├── domain/ │ ├── infrastructure/ │ └── interfaces/ ├── payment/ ├── fulfillment/ └── query/两种方式并非互斥。工程初期先明确依赖方向,业务复杂后再按子域垂直拆分,比一开始机械套用大量目录更务实。7. 父 POM 与版本治理7.1 父 POM 完整示例?xml version="1.0" encoding="UTF-8"?projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"modelVersion4.0.0/modelVersiongroupIdcom.lightning/groupIdartifactIdlightning-order/artifactIdversion1.0.0-SNAPSHOT/versionpackagingpom/packagingnamelightning-order/namemodulesmoduleorder-contract/modulemoduleorder-domain/modulemoduleorder-application/modulemoduleorder-infrastructure/modulemoduleorder-interfaces/modulemoduleorder-bootstrap/modulemoduleorder-test-support/module/modulespropertiesjava.version21/java.versionmaven.compiler.release${java.version}/maven.compiler.releaseproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingspring-boot.version4.0.0/spring-boot.versionspring-cloud.version2025.1.0/spring-cloud.versionspring-cloud-alibaba.version2025.1.0.0/spring-cloud-alibaba.versionmybatis-plus.version3.5.13/mybatis-plus.versionmapstruct.version1.6.3/mapstruct.versionjib.version3.5.3/jib.versiontestcontainers.version1.21.3/testcontainers.versionmaven-compiler-plugin.version3.14.0/maven-compiler-plugin.versionmaven-surefire-plugin.version3.5.3/maven-surefire-plugin.versionmaven-failsafe-plugin.version3.5.3/maven-failsafe-plugin.versionmaven-enforcer-plugin.version3.6.1/maven-enforcer-plugin.version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion${spring-cloud-alibaba.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-spring-boot4-starter/artifactIdversion${mybatis-plus.version}/version/dependencydependency