第一站 - 轻松上网从此开始!

上网第一站

当前位置: > SEO >

不就是一个订票网站吗 12306 的核心模型设计思路究竟复杂在哪里?(4)

时间:2016-02-26 08:49来源:网络整理 作者:跌名 点击: 我来投稿获取授权
以下内容来自网络或网友投稿,www.swdyz.com不承担连带责任,如有侵权问题请联系我删除。投稿如果是首发请注明‘第一站首发’。如果你对本站有什么好的要求或建议。那么都非常感谢你能-联系我|版权认领
所以,通过这样的思路,我们将一次订票的处理控制在了一个聚合根里,用聚合根内的强一致性的特性保证了订票处理的强一致性,同时也保证了性能,免

  所以,通过这样的思路,我们将一次订票的处理控制在了一个聚合根里,用聚合根内的强一致性的特性保证了订票处理的强一致性,同时也保证了性能,免去了并发冲突的可能性。传统电商那种把票单做类似商品的核心聚合根的设计,我当时第一眼看到就觉得不妥。因为这违背了 DDD 强调的强一致性应该由聚合根来保证、聚合根之间的最终一致性通过 Saga 来保证的原则。

  还有一个很重要的概念我想说一下我的看法,就是座位和区间的关系。因为有些朋友和我讲,考虑座位号的问题,虽然都能减 1,座位号也必须是同一个。我觉得座位是全局共享的,和区段无关(也许我的理解完全有误,请大家指正)。座位是一个物理概念,一个用户成功购买了一张票后,座位就会少一个,一张票唯一对应一个座位,但是一个座位有可能会对应多张票;而区间是一个逻辑上的概念,区间的作用有两个:1)表示票的出发地和目的地;2)记录票的可用数额。如果区间能连通(即该区间内的每个原子区间的可用数额都大于 0),则表示允许拥有一个座位。所以,我觉得座位和票(区间)是两个维度的概念。

  3、如何为票分配座位?

  我觉得车次聚合根内部应该维护所有该车次已经售出的票,已经出售的票的的本质是区间和座位的对应关系。系统处理订票时,用户提交过来的是一段区间。所以,系统应该做两个事情:

  先根据区间去判断是否有可用的座位;

  如果有可用座位,则再通过算法去选择一个可用的座位;

  当得到一个可用座位后,就可以生成一张票了,然后保存这个票到车次聚合根内部即可。下面举个例子:

  假设现在的情况是座位有 3 个,站点有 4 个:

  座位:1,2,3

  站点:abcd

  票的卖法 1:

  票 1:ab,1

  票 2:bc,2

  票 3:cd,3

  票 4:ac,3

  票 5:bd,1

  这种选座位的方式应该比较高效,因为总是优先从座位池里去拿座位,只有在万不得已的时候才会去回收可重复利用的票。

  上面的 4,5 两个票,就是考虑回收利用的结果。

  票的卖法 2:

  票 1:ab,1

  票 2:bc,1

  票 3:cd,1

  票 4:ac,2

  票 5:bd,3

  这种选座位的方式应该相对低效,因为总是优先会去扫描是否有可回收的座位,而扫描相对直接从座位池里去拿票总是成本相对要高的。

  上面的 2,3 两个票,就是考虑回收利用的结果。

  但是,优先从座位池里拿票的算法有缺陷,就是会出现虽然第一步判断认为有可用的座位,但是这个座位可能不是全程都是同一个座位。举例:

  假设现在的情况是座位有 3 个,站点有 4 个:

  座位:1,2,3

  站点:abcd

  票的卖法 3:

  票 1:ab,1

  票 2:bc,2

  票 3:cd,3

  现在如果有人要买 ad 的票,那可用的座位有 2,或者 3。但是无论是 2 还是 3,都要这个乘客中途换车位。比如卖给他座位 2,那他 ab 是坐的座位 2,但是 bc 的时候要坐座位 1 的。否则拿票 2 的那个人上车时,发现座位 2 已经有人了。而通过优先回收利用的算法,是没这个问题的。

  所以,从上面的分析我们也知道选座位的算法该怎么写了,就是采用优先回收利用座位的算法。我认为不管我们这里怎么设计算法,都不影响大局,因为这一切都只发生在车次聚合根内部,这就是预先设计好聚合根,明确出票职责在哪个对象上的好处。

  4、模型分析总结

  我认为票不是核心聚合根,票只是一次出票的结果,一个凭证而已。

  12306 真正的核心聚合根应该是车次,车次具有出票的职责,一次出票具体做的事情有:

  判断是否可出票;

  选择可用的座位;

  更新一次出票时所有原子区间的可用票数,用于判断下次是否能出票;

  维护所有已售出的票,用于为选择可用座位提供依据。

  通过这样的模型设计,我们可以确保一次出票处理只会在一个车次聚合根内进行。这样的好处是:

  不需要依赖数据库事务就能实现数据修改的强一致性,因为所有修改只在一个聚合根内发生;

  在保证数据强一致性的同时还能提供很高的并发处理能力,具体设计见下面的架构设计。

  5、架构设计

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发布者资料
第一站编辑 查看详细资料 发送留言 加为好友 用户等级:注册会员 注册时间:2012-05-22 19:05 最后登录:2014-08-08 03:08
栏目列表
推荐内容
分享按鈕