马上春节了,又到了火车票的销售旺季,一票难求的问题依旧存在吗?还记得10年前春节前买火车票得在放票前1天搬个小板凳去排队,对于热门路线,排一个晚上都有可能买不到票。
随着互联网的发展,几年前建设了12306网上购票系统,可以从电脑上买票,但是不要以为在电脑上就能买到票。
我记得12306刚推出时,经常发生12306网站打不开,无法付款的问题。
为什么呢?
原因很简单,春节期间网上购票的人可能达到几亿的级别,而且放票日期是同一天同一个时间点,也就是说同一时刻12306要接受几亿用户的访问。处理能力和实际的访问需求更不上,带来的结果就是网站打不开,系统不稳定的现象。
后来12306想了分线路分时段开启的办法,想办法把不同线路的用户错开时间来访问12306的网站,但是这个方法起初的效果不明显,并不是所有用户都知道的(就好像你临时通知今天不上班,但还是有用户会来单位的),所以大多数用户还是集中在一个点去访问12306的网站。
随着硬件的发展,技术的演进,12306的系统越来越趋于成熟,稳定性和响应速度也越来越好。
据说现在很多商家还开通了云抢票业务,本质上是让你不要冲击12306系统了,把需求提前收集,在放票时,这些系统会进行排队与合并购买,这种手段可以减少12306的访问并发。
抢火车票是很有意思的一个课题,对IT人的智商以及IT系统的健壮性,尤其是数据库的功能和性能都是一种挑战。
接下来我们一起来缕一缕有哪些难点,又有怎样的解决手段。
一、铁路售票系统 - 西天取经之路开始啦铁路售票系统最基本的功能包括
查询余票、余票统计、购票、车次变化、退票、改签、中转乘车规划 等。每个需求都有各自的特点,例如
1. 查询余票,用户在购票前通常会查一下到达目的地有哪些余票,它属于一个高并发的操作,同时需要统计余票张数,需要很强的CPU来支撑实时的查询。
2. 购票,购票和查询不一样,购票是会改变库存的,所以对数据库来说是更新的操作。而且购票很可能发生冲突,例如很多人要买同一趟车的票,那就出现冲突了,到底卖给谁呢?需要考虑锁冲突,尽量的让不同的人购买时可并行,或者可以合并多人的购票请求,来减少数据库的更新操作。
3. 中转乘车,当用户需要购买的起点和到达站无票时,需要计算中转的搭乘方案。
比如从北京到上海,如果没有直达车,是不是该转车呢?转哪趟,在哪里转就成了问题,简单一点就是买票的人自己想。
高级一点的话,可以让12306给你推荐路线,这个涉及的是数据库的路径规划功能。
我们来逐一分析一下这些需求的特点。
1 查询余票1. 普通的余票查询需求
你如果要买从北京到上海的火车票,通常会查一下哪些车次还有余票。
查询的过滤条件可能很多,比如
1.1. 上车站、下车站、中转站
1.2. 车次类型(高铁、动车、直达、快速、普客、...)
1.3. 出发日期、时段
1.4. 到达日期、时段
1.5. 席别(硬座、硬卧、...站票)
1.6. 过滤掉没有余票的车次
展示给用时还要考虑到怎么排序(是按始发时间排呢,还是按票价,或者按余票数量排?),怎么分页。
眼见不一定为实查询余票通常不是实时的、或者说不一定是准确的,有可能是后台异步统计的结果。
即使是实时统计的结果,在高并发的抢票期间,你看到的信息对你来说也许很快就会失效。
比如你看到某趟车还有100张票,很可能等你付款的时候,已经卖光了。
所以在高峰期,余票信息的参考价值并不大,不要被迷惑了。
2. 查询余票的另一个更高级的需求是路径规划, 自动适配(根据用户输入的中转站点s)
这个功能以前可能没有,但是总有一天会暴露出来,特别是车票很紧张的情况下。
就比如从北京到上海,直达的没有了,系统可以帮你看看转一趟车的,转2趟车的,转N趟车的。(当然,转的越多越复杂)。
从中转这个角度来讲,实际上已经扯上路径规划的技术了。
怎么中转是时间最短的、价格最低的、中转次数最少的等等。(里面还涉及转车的输入要求(比如用户要求在一线城市转车,或者必须要转高铁))。
关于路径规划,可以参考一下PostgreSQL pgrouting,已支持多种路径规划算法,支持算法的自定义扩展。
简直是居家旅行,杀人灭口的必备良药。《聊一聊双十一背后的技术 - 物流, 动态路径规划》
师父小心,有妖怪。。。
1. 大多数用户是有选择综合症的,通常来说,用户可能会查询很多次,才选到合适日期的合适车次的票。
查询量比较大,春节期间更甚。
2. 为了展示余票数量,需要统计,会耗费较多的CPU, IO资源。
3. 路径规划,帮用户选择最佳的转车路线,很考验数据库的功能,大多数数据库没有这个功能。
2 余票统计对于售票系统来说,查询余票实际上是一个统计操作。
统计操作相比简单查询,不但消耗