沉默是金,总会发光
大家好,我是沉默
每到春节、国庆这种全民迁徙的时刻,大家都会经历过一个共同的痛点:
火车票,开售瞬间就没了。
很多人可能不知道,12306 在放票瞬间所承受的压力,堪称全世界最极限的 秒杀系统。
几亿人同时点下“确认”按钮,全国范围的“并发洪峰”一齐打到后台,这种 QPS(每秒请求量)在电商大促、游戏秒杀面前,都是碾压级的存在。
那么,12306 是怎么做到在这种地狱模式下依然稳如老狗的呢?
今天,我们就从架构师的角度,扒一扒 12306 背后的高并发设计思路。
**-**01-
分而治之,层层负载均衡
大厂架构的第一原则:流量不能直接打死服务器,要先“分而治之”。
12306 的请求要经过三层负载均衡:
-
OSPF 路由:保证线路最优、链路可容灾;
-
LVS 内核级调度:高吞吐,把请求分摊到后端服务器;
-
Nginx 应用层负载:按权重、IP 等维度再做细分调度。
这样设计的好处就是:哪怕几百万 QPS 砸过来,也能像水流一样被分散到不同机器处理。
(如果你用 Nginx 做过加权轮询,就能直观感受到它在流量调度上的丝滑感)
- 02-
订单扣库存的艺术
很多人以为抢票就是“先下单,再付款”,但在极限并发下,这么玩会出大问题:
-
先下单再减库存:会被恶意下单拖死,库存被锁死。
-
先付款再减库存:容易超卖,用户付款了却发现没票。
12306 采用的是 预扣库存:
-
用户点下单时,先从库存里“锁定一张票”;
-
系统再异步生成订单,给用户支付;
-
用户不付款,5 分钟后票会自动释放回库存。
这一招堪称点睛之笔,既避免了超卖,又避免了少卖。
- 03-
单机极限性能优化
哪怕请求被均匀分摊,每台服务器仍要承受巨大的并发。
于是 12306 的优化重点变成:
尽量少碰数据库磁盘 IO,一切操作尽量走内存。
-
本地库存:每台服务器先维护一部分票存在内存里,抢票时直接在本地扣,超快响应;
-
Redis 统一库存:保证不超卖,每次本地扣库存后,还要同步扣 Redis。
-
Buffer 冗余:就算有几台机器宕机,Redis 还能兜底,避免“少卖”。
这里 Redis 单机能抗 10W QPS,配合 Lua 脚本保证原子性,性能与正确性两手抓。
**-****04-**合理使用并发 + 异步
12306 的系统哲学,可以总结为一句话:
“能内存就别落盘,能异步就别同步,能分布就别集中。”
-
Nginx/Redis/NodeJS 这种基于 epoll 的网络模型,单线程也能顶万级并发。
-
Java 提供了 线程池(ExecutorService)和 并发工具类,适合并发场景,每个请求都能在独立协程里处理。
-
MQ 异步队列,把下单、支付、释放库存拆开,保证核心流程不卡死。
压测案例
即便是在笔者本地低配 Mac 上,用 Java 写的秒杀 demo,单机也能轻松跑出 4000+ QPS;
换到线上多核服务器,单机处理 1W+ QPS 完全不是问题。
日志里显示:
-
没有超卖;
-
没有少卖;
-
Redis、Nginx 全程稳定运行。
**-****05-**总结
12306 能在春运的流量洪峰下扛得住,靠的是一整套成熟的高并发架构:
负载均衡 → 流量分而治之,层层拦截。
预扣库存 → 避免超卖/少卖。
本地 + Redis 双库存 → 性能与正确性兼顾。
异步化设计 → 系统稳定不卡死。
很多程序员看完都会感叹:
原来“买火车票”这件小事背后,藏着的是世界级的分布式架构艺术。
而我觉得,12306 的牛逼之处,不只是“能抗住几亿人抢票”,
更在于它把复杂的架构问题,抽丝剥茧地化解成了简单有效的策略。
这,才是真正的大国工程级互联网系统。 🚄💨
**-****05-**粉丝福利
我这里创建一个程序员成长&副业交流群,
和一群志同道合的小伙伴,一起聚焦自身发展,
可以聊:
技术成长与职业规划,分享路线图、面试经验和效率工具,
探讨多种副业变现路径,从写作课程到私活接单,
主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。
如果你对这个特别的群,感兴趣的,
可以加一下, 微信通过后会拉你入群,
但是任何人在群里打任何广告,都会被我T掉。