ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

12306高并发架构设计:基于区间计数器的网关层拒单方案

12306高并发架构设计:基于区间计数器的网关层拒单方案

引言

在上一篇文章《重新理解12306:它卖的从来不是“库存”,而是“状态”》,我们深入探讨了12306的业务模型核心:它不是简单的库存管理系统,而是基于座位段的状态管理。每个座位被拆分为多个段(例如A-B、B-C、C-D等),售出票时实际是原子性地锁定连续段的使用权。这种模型带来了独特的并发挑战——如何在高并发请求下快速拒绝无效订单,减轻下游系统压力。

假设一列车有1000个座位,同一时刻可能有100万(瞎猜)用户抢票,但最终能成功的只有极少数。如果让所有请求都进入核心下单流程,系统必然崩溃。那么,如何在网关层就识别并拒绝绝大部分无效请求?传统电商的库存计数方案在这里失效了,因为12306的“库存”是动态关联的座位段。

本文将揭示一种高效的架构方案:基于区间计数器的网关层拒单策略。通过这种方案,我们能够将百万并发过滤为可管理的十几万请求,保证系统稳定运行。

核心思路:区间计数器粗粒度过滤

为什么传统库存计数方案不适用?

在传统电商中,我们可以在网关层设置库存计数器:当某商品库存为0时,直接拒绝所有购买请求。但12306的情况截然不同:

  1. 它不是简单减库存,而是需要找到连续座位段并锁定
  2. 同一个座位可以被拆分为多个区段(如A-B、B-C、C-D)售予不同乘客
  3. 不同区间组合(如北京-上海、北京-南京、南京-上海)相互关联且竞争同一座位资源

区间计数器的基本原理

虽然12306的座位段模型复杂,但有一个关键特性:对于任意区间组合(如北京南-上海虹桥),最多可售出的票数不会超过列车总座位数。也就是说,无论有多少种不同的上下车组合,一趟列车的总运力是固定的。

基于这一原理,我们可以为每个区间组合设置一个计数器:

  • 当某个区间组合的请求数达到列车总座位数时,后续请求可直接拒绝
  • 例如:一列车有1000个座位,那么"北京南-上海虹桥"这个区间最多只能有1000个请求通过

计数器数量计算

假设一趟列车有20个站点,那么可能的区间组合数量为:

C(20, 2) = 20 × 19 / 2 = 190

如果列车有1000个座位,那么网关层需要处理的最大请求量为:

190 × 1000 = 171,000

这个数字相比最初的100万并发,已经减少了83%以上!而且这171000请求还可以通过缓存和异步处理进一步消化。

架构设计

整体架构图

用户请求 → 网关层 → Redis计数器 → 消息队列 → 后端服务 → 数据库

详细流程

1. 用户请求到达网关

    • 请求包含车次、起始站、终点站信息
    • 示例:{车次: "G101", 起始站: "北京南", 终点站: "上海虹桥"}

2. 生成区间键

    • 根据请求参数生成唯一键
    • 示例:生成键 "G101:北京南:上海虹桥"

3. 计数器检查

    • Redis计数器值 ≥ 总座位数(如1000),立即拒绝请求,返回“无票”
    • 否则,原子性地递增计数器,并允许请求通过

4. 异步处理

    • 通过的请求被送入消息队列(如Kafka或RabbitMQ)
    • 后端服务异步消费队列,执行实际的座位段锁定和订单创建

5. 计数器校准(可选)

    • 后端处理完成后,根据结果调整计数器
    • 处理失败时递减计数器,避免过度拒绝

关键组件详解

网关层

网关层是整个系统的第一道防线,需要具备极高的性能和可靠性:

  • 选择高性能API网关:如Nginx+OpenResty
  • 实现限流机制:防止单个用户或IP发送过多请求
  • 保持无状态设计:方便水平扩展

Redis计数器存储

Redis作为内存数据库,提供高速的计数器操作:

  • 使用原子操作:保证并发下的数据一致性
  • 设置过期时间:自动清理过期车次的计数器
  • 分片存储:根据车次或区间哈希分布到多个实例,避免热点

消息队列

消息队列起到削峰填谷的作用:

  • 选择高吞吐量消息队列:如Kafka或RabbitMQ
  • 配置多个消费者组:并行处理不同车次的请求
  • 实现死信队列:处理多次失败的消息

后端服务

后端服务负责精确的座位分配:

  • 实现分布式事务:保证座位锁定和订单创建的一致性
  • 设计幂等操作:防止重复处理同一请求
  • 采用批量处理:提高数据库操作效率

 

方案优势

  1. 高效过滤:能在网关层拒绝80%以上的无效请求
  2. 简单可靠:基于Redis的计数器方案易于实现和维护
  3. 可扩展性:通过分片和异步处理,系统可以水平扩展​

总结

12306这类系统的高并发挑战并非无解。关键在于识别出业务模型中“每区间出票存在上限”这一核心特征,并据此在网关层实施区间计数过滤。通过粗粒度的请求控制,将极大部分的无效并发挡在门外,从而为后端复杂事务争取更多的处理资源与时间。

返回列表