基于 Spring Boot、Spring Cloud、MySQL、Redis、Redisson、RocketMQ 实现的分布式购票系统,聚焦区间余票查询、并发锁座、防超卖、延迟取消与订单补偿。
- 参考 12306 业务场景实现区间售票,而不是整趟列车一次性售卖
- 核心链路覆盖查票、锁座、下单、支付确认、超时取消、库存回补
- 重点验证高并发下的前置削峰、幂等控制、分布式锁和库存一致性
- 后端:Java 17、Spring Boot、Spring Cloud Gateway、OpenFeign、MyBatis-Plus
- 数据与中间件:MySQL、Redis、Redisson、RocketMQ
- 前端:Vue 3、TypeScript
gateway-service:统一入口与路由转发user-service:用户与乘车人信息管理ticket-service:查票、token 管理、锁座、确认车票、释放座位、购票幂等order-service:创建订单、支付确认、取消订单、延迟消息、补偿任务frontend:购票页面与下单交互
将一个物理座位拆成多个相邻站点间的 segment,按 出发站 -> 到达站 计算是否可售。
这样可以支持区间复用,避免把整趟车库存简单粗暴地一次锁死。
购票主链路采用四层控制:
Redis Token前置拦截无效请求Redis幂等控制拦截重复提交Redisson分布式锁降低同车次同席别并发冲突MySQL条件更新作为最终库存兜底
其中 Redis 和锁负责削峰与互斥,MySQL 负责最终判断是否锁座成功。
- 创建订单后发送 RocketMQ 延迟消息
- 到期未支付时触发取消订单与释放座位
- MQ 发送失败或资源释放失败时,写入补偿任务异步重试
- 通过订单状态机幂等控制,避免重复消费把已支付订单再次取消
- 根据
trainId + departure + arrival定位目标区间 - 计算区间覆盖的全部座位段
- 统计各席别剩余可售座位数
- 校验乘车人与购票请求
- 执行 token 前置校验与幂等校验
- 获取分布式锁并尝试锁座
- 写入车票与订单数据
- 发送延迟取消消息
order-service更新订单为已支付- 事务提交后调用
ticket-service确认车票 - 确认失败则写入补偿任务
- 延迟消息到期后消费取消逻辑
- 仅允许
WAIT_PAY -> CANCELED - 事务提交后释放座位并回补资源
- 利用
Redis实现购票请求幂等前置拦截 - 将高并发重复购票请求平均响应时间由约
2069ms降低至约31ms - 减少无效请求进入分布式锁与下游订单链路
- 基于
Redisson分布式锁与MySQL条件更新控制库存竞争 - 在
100并发用户同时购票、余票仅剩3张的场景下 - 最终成功
3单、失败97单,验证未发生超卖
- 通过显式绑定
RocketMQ Broker地址 - 解决多网卡环境下 Broker 自动注册错误 IP 导致的消息发送失败与延迟消费异常
- JDK 17
- MySQL 8.x
- Redis
- RocketMQ
- Node.js 18+
- 执行
resources/db下的建表 SQL - 启动
user-service - 启动
ticket-service - 启动
order-service - 启动
gateway-service - 启动
frontend
- 网关:
http://localhost:8080 - 前端:
http://localhost:5173
- 用
Redis Hash + Lua优化区间 token 的精细化扣减 - 增加更完整的监控、告警与压测链路
- 优化多乘客邻座分配策略