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

news/2025/9/21 23:04:29/文章来源:https://www.cnblogs.com/leilijun/p/19104346

引言

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

各位同学,大家好!我想请大家回忆一段我们在刘集中学的故事,和我单独联系。我想把这些故事写出来保存。欢迎与我分享!谢谢!

各位同学,大家好!我想请大家回忆一段我们在刘集中学的故事,和我单独联系。我想把这些故事写出来保存。欢迎与我分享!谢谢! 初三时周杰伦的歌曲开始出现,有段时间教室早上会播放他的歌曲,又《双截棍》《霍元甲》…

实用指南:centos sshd:xxx.xxx.xxx.xxx:allow 如何设置

实用指南:centos sshd:xxx.xxx.xxx.xxx:allow 如何设置pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

fedora无法看视频?编解码器详细安装教程

fedora无法看视频?编解码器详细安装教程启用rpm fusion 包 free包: sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm nofree包: sudo dnf ins…

vite7-vue3-os网页os管理|vue3+vite7+arco.design网页pc版webos系统

最新研发Vite7+Vue3+Pinia3+Arco仿macos/windows网页版webos管理系统。 vite7-webos原创基于vite7.1+vue3.5+pinia3+arco-design+echarts从0-1搭建pc网页版os式管理系统模板。支持macos+windows两种桌面布局风格、自定…

高并发高吞吐量

Java实现高并发需从底层机制、并发控制、资源调度、架构设计、编码细节等多维度系统优化,每个维度聚焦特定技术方向,覆盖从底层到应用的全链路性能提升: 一、底层IO与网络优化(提升数据传输效率)IO模型升级网络通…

服务降级

目录背景和价值高可用架构中的服务降级举措一、核心逻辑:非核心功能“断舍离”二、体验妥协:核心功能“降质保核”三、依赖防护:外部/下游依赖“解耦降级”四、降级实施的关键支撑:动态化与精细化参考资料 背景和价…

python读取csv文件后,打印内容再return返回内容,返回值为空

View Postpython读取csv文件后,打印内容再return返回内容,返回值为空1、以下代码返回值是正确的 `import os,csv def read_csv(path): with open(path, r, encoding=utf-8) as f: res = csv.reader(f) return list(r…

【C++】第十三节—stack、queue、priority_queue、容器适配器(介绍和使用+模拟搭建+OJ题)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

镜像制作

Docker 镜像制作:https://cloud.tencent.com/developer/article/1544404?from=15425&frompage=seopage本文来自博客园,作者:Daisy0312,转载请注明原文链接:https://www.cnblogs.com/brooklyndawndaisy-20171…

实用指南:手机群控平台的工作效率

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20231427田泽航第二周预习报告

1.AI对学习内容的总结 这份文档《娄哥-第1-2章.pdf》系统地介绍了密码学的基础知识及其在C/C++环境下的开发实践。以下是对其内容的总结:第1章:密码学概述 1.1 历史背景与重要性密码学起源于远古,早期主要用于军事、…

IAR Embedded Workbench中的MCU启动过程分析

在嵌入式系统中,当MCU复位之后,需要运行对应的启动代码来对系统进行初始化,然后才会调用main函数,开始运行用户的代码。通常情况下,对应的启动代码一般是工具厂商或者芯片厂商提供,嵌入式软件开发工程师不需要特…

CSP-S 2025

/* 又是一年CSP,也许是最后一次了罢?谁知道呢。 经典GD CSP必下雨,被淋透了。半睡半醒地下大巴,今年为什么全ZS都去JZ啊,完全不分流可还行。 说不紧张都是假的,毕竟考不好真退役了。唉呦我去讨论区怎么这么多钓鱼…

ENVI系列教程(七)——自定义 RPC 资料图像正射校正

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

(多线程)线程安全和线程不安全 产生的原因 synchronized关键字 synchronized可重入特性死锁 如何避免死锁 内存可见性 - 详解

(多线程)线程安全和线程不安全 产生的原因 synchronized关键字 synchronized可重入特性死锁 如何避免死锁 内存可见性 - 详解2025-09-21 22:20 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !impo…

Linux 笔记本充电限制【转发】

Linux 笔记本充电限制【转发】https://www.bilibili.com/opus/970651970527297540 最近主要把笔记本放家里用。在学校用的时候搬来搬去,当然充满电最好。然而如果是固定地用,只要插电就行了,电量无所谓。 对于大部分…

别样的CSP-S初赛大战(又名:我和油一的那些年)

一次平凡的出行勾起的胡思乱想。事实上,这篇文章和标题有关的内容并不是很多,所以我补了个又名。但它的全部确实是由此引起的。(引用可以这样使用么?><今年的气温转变得很突然。前两天我还在嫌弃机房的空调太…

第01周 预习、实验与作业:绪论与Java基本语法

1.【1】企业级服务器后端开发 【2】Web应用后端/API构建 【3】Android移动应用等邻域 2.【1】Java程序编译一次就会生成.class文件,在任何有安装Java虚拟机(JVM)的操作系统上都能运行,不用重新编译。 【2】要安装J…

刷新记录:TapData Oracle 日志同步性能达 80K TPS,重塑实时同步新标准 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …