如何处理12306.cn指定座位的需求

来源:互联网 发布:主流的社交软件 编辑:程序博客网 时间:2024/06/05 08:46

CSDN上有很多大牛的文章,已经提到了对12306.cn的很多建议。我比较赞同的有:

1. CDN镜像

2. 减少静态资源请求(包括压缩减少带宽)

3. 将列车座位分表,分区存放

4. 负载均衡

5. 查询优化

6. ...

以上设计请自行搜索。


本文仅针对12306.cn近期推出的订票时可指定座位号的需求。

如果要指出和该需求最类似的场景,我认为是证券行业的实时交易系统。一边是卖出委托,一边是买入委托,卖出的不知道是否有人买,买入的也不知道是否有人卖,反正把订单提交上去就等着。后台有一个交易配对的处理程序,当双方委托价格、数量合适,即将双方的委托进行实时交易,并通知处理结果。


将订票需求和证券交易类比后,可以将座位号(可售未发车次)设计为卖出委托,实时提交的订单设计为买入委托。卖出委托按照车次(含日期时间)分库分表分区存放,买入委托除了按照车次(含日期时间)分库分表分区存放外,还需要按照委托时间分表存放,即每几小时生成一个新表存放。


订单系统接受客户的买入委托,分析订单信息,将订单实时插入到不同数据库的相应买入委托表等待处理。

为避免垃圾订单过多,可将已售空车次做标记,并在内存中缓存,遇到已售空车次,订单直接失败,不进入买入委托。

另外,每天对已发车次做转储,过期作废订单做定时清空处理。


交易配对以独立程序运行,可多进程分区域同时运行,且不和订单系统合并部署。交易配对系统的处理逻辑为:

1. 从数据库中取出本进程需要处理的未售完车次列表,并取第一优先处理车次(优先级可采用未处理订单数量,以及最近处理时间来计算);

2. 判断该车次是否已售完,如果已售完,则将车次从列表中删除,更新全部未处理订单为失败,并重复第1步;

3. 根据车次(含日期和时间)从买入委托表中按委托时间先后取出一批订单;

4. 循环每个订单,如果订单和本批次已处理的订单座位号不重复,则将订单信息处理为ATask,提交给订单处理线程池处理;否则订单加入到失败集合;

5. 将失败集合处理成一个BTask,提交给订单处理线程池处理;

6. 等待线程池发送有空闲处理能力信息;

7. 更新车次座位是否已全部发售完毕(该车次的全部卖出委托为预售或已付款)

8. 重复第1步;


订单处理线程池处理ATask过程为:

1. 判断该订单(买入委托)申请的座位号(卖出委托)状态是否为预售或已付款;如果已售,将买入委托更新为失败;如果未售,更新买入委托状态为待付款;更新卖出委托状态为预售;


订单处理线程池处理BTask过程为:

1. 批量更新买入委托状态为失败;


取消委托,付款等其他处理略。


优点:

交易配对程序可以部署很多很多个,甚至可以为每个车厢部署一个;


特点:

订单系统收到的所有买入委托的变更请求,都要以消息的形式通知交易配对程序,比如增加订单、取消订单、付款。


原创粉丝点击