还有一个月就是春节了,而买一张车票回家团圆,是咱们中国的最大的心愿,因此12306也迎来购票高峰。 铁路部门预计,2020年1月22日(腊月二十八)、1月23日(腊月二十九)为出行高峰期,火车票购票日的12月24日和25日也将迎来抢票最高峰。根据今年来春运人数胡统计情况来看,2020年春运出行的人数估计在30亿左右。
年份 | 铁路 | 公路 | 水路 | 航空 | |
2011 | 2.3亿 | 26.4亿 | 3260 | 4000万估 | 30亿 |
2012 | 2.35亿 | 28.47 | 3488万 | 4245.1万 | 31亿 |
2013 | 2.40亿 | 31亿 | 3810万 | 4250万 | 34亿 |
2014 | 2.66亿 | 32.8亿 | 4200万估 | 4344.8万 | 36亿 |
2015 | 2.95亿 | 24.22亿 | 4914万 | 4284万 | 28.09亿 |
2016 | 3.25亿 | 24.95亿 | 5140万 | 4260万 | 29.1亿 |
2017 | 3.57亿 | 25.21亿 | 5854.8万 | 4397.6 | 29.81亿 |
虽然收自驾拼车等新兴方式影响,春运总人数在呈下降趋势,不过乘坐铁路的人数却还是稳步上升,今年乘坐铁路回家探亲的人数估计会在4亿左右。
不过12月23日的第一给抢票高峰,12306又崩溃了,在查询回家车票的时候总是出现车次加载失败。
12306太难了
虽然12306与阿里云合作以后已经很少再见到崩溃现象了,具体这段历史笔者在《神龙飞天,国士王坚》中已经介绍过了这里不再赘述,谈到高并发问题,我们总是想到在“鹿晗公布恋情”的时候系统没抗住,微博在经过架构改进后表示今后可以同时支持 8 位明星并发出轨,然而在“赵丽颖、冯绍峰官宣结婚”事件上,还是没撑住。一般来说,典型的秒杀系统都会使用分布式的技术给每个服务节点分配一定的本地库存,再通过消息队列及缓存等技术对全局库存进行减少,具体见下图。
不过12306和一般的商城、社交类的秒杀系统有很大不同,还要解决分布式、缓存、负载均衡问题。主要有以下两个效应影响最大:
1. 分布式架构不完全适合火车票: 2015 年春运售票量就已经超过600万,达到 636 万 / 天,而在2019年的1月4日日页面PV量达 1310.6 亿次,全天发售车票 1282 万张。虽然这个量与双十一的动辙十亿的天量相比不算什么,但是由于火车票与普通商品不同,他是分站发售的,举个例子北京到广州有24站,当我买下这一张全程票时,需要将将区间所有的票全部下架,共计24!=300。所以12306很难将库存分给每个server本地库存,据笔者所知只能是将全程票分一部分给本地,其实的区间票还是要中心化,而如何把区间化的车票也进行合理分布本身是个问题,而且受区间售票的杠杆效应影响,1200多万的日发售量,实际对应的普通商品销量的10倍甚至更多。
2.查询/下单数比过高:目前12306的查询交易占比超过90%,虽然阿里未公布相关数据,不过从笔者实际经验看,“双十一”笔者不再会再浏览商品或者比价了,只是直接参与活动罢了,所以查询交易量应该不会达到90%的占比。而频繁的查询请求也会增加12306的压力。
12306如何应对
正如上文所述,12306做到不崩溃的难度真的很大,而且笔者也没有这种大型秒杀系统的项目经验,这里抖胆提出以下建议:
将订票方式变为预定订票:我们知道秒杀的场景的设计,其初衷是电商为了提升用户参与度,增加用户投入的一种营销手段。而12306似乎没必要使用这种方式来进行销售,比如某些重点路线给予5分钟的预定窗口,再汇总各服务节点记录用户订单,按照先到先得的方式集中处理,将实时订单处理变为批量订单处理,这种方式在笔者一直工作的银行当中是屡试不爽的缓释系统压力的有效方式。
给程序员们的推荐购票方案
咱们程序员群体真的没必要再使用什么12306网站进行订票了,笔者在这里也推荐一下之前的一篇博客《Github上的开源工具帮助你实现“十一”回家的愿望》提到的购票工具(https://github.com/testerSunshine/12306),它完全可以满足这个目标。当然由于此类工具全部依赖于tensorflow进行验证码的自动输入,所以为了快人一步还是有个比较快的显卡更为妥当。因为这个软件完全是基于人工模拟点击的方式风险不大,只要不进行大规模使用应该没什么问题。
不过笔者也发现在Github上还有一些软件做了多线程、集群化抢票的功能,因为这种使用方式很可能会触及《数据安全管理办法》中所规定“不得通过恶意爬虫危及网络安全”的规定,所以这里并不推荐大家使用集群化秒杀的软件进行火车票的抢购。