12306主要性能问题还是出在出票和余票查询。当前通过CQRS架构结合聚合根在内存、事件回溯的手段来解决以上两个问题。 实现了买票、退票、站点最多可卖座位数限制、 站点间预留票(最低保留座位数,最多可卖座位数)、取消预留票功能。这里CQRS架构不做过多的描述,主要针对用到两个数据结构跳表、位图结合来高效的实现库存管理。
假设车次k41有途径4个站点分别为1,2,3,4,总共8个座位。
1.初始化车次站点票信息
10002 表示表示站点1到站点2, 0000 0000 表示有8个座位,下标从0-7.
20003 表示表示站点2到站点3, 0000 0000 表示有8个座位,下标从0-7.
30004 表示表示站点3到站点4, 0000 0000 表示有8个座位,下标从0-7.
10002 0000 0000
20003 0000 0000
30004 0000 0000
数据结构: 跳表 + 位图
ConcurrentSkipListMap<Integer, BitSet>
2.购票站点1到站点3的票2张
找出站点1到站点3的区间,有10002,20003两段(跳表范围查找)。
10002 0000 0000
or 运算
20003 0000 0000
0000 0000
购买第一张车票,第一位是0,说明这个位置可以购票。购票后更新为10002 20003 索引0的值为1
10002 1000 0000
20003 1000 0000
---------------------------------------
10002 1000 0000
or 运算
20003 1000 0000
1000 0000
购买第二张车票,第二位是0,说明这个位置可以购票。购票后更新为10002 20003 索引1的值为1
10002 1100 0000
20003 1100 0000
---------------------------------------
如果10002 or 20003 如下,则表示站点1到站点3已无座位可卖
10002 1111 1111
or 运算
20003 1111 1111
1111 1111
3.区间预留票
假设需要预留站点1到站点2的票2张.可以用以下表示
10002 1100 0000
4.具体示例