加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 综合聚焦 > 创业热点 > 经验 > 正文

浅谈 12306 核心模型设计思路和架构设计

发布时间:2016-02-17 17:43:02 所属栏目:经验 来源:51CTO
导读:春节期间,无意中看到一篇文章,文章中讲到12306的业务复杂度远远比淘宝天猫这种电商网站要复杂。后来自己想想,也确实如此。所以,很想挑战一下12306这个系统的核心领域模

另外一个问题我觉得还需要提一下,因为用户订票成功后,还需要付款。但用户有可能不去付款或者没有在规定的时间内完成付款。那这种情况下,系统会自动释放该用户之前订购的票。所以基于这样的需求,我们在业务上需要支持业务级别的2pc。即先预扣库存,也就是先占住这张票一定时间(比如15分钟),然后付款成功后再真实给你这张票,系统做真正的库存修改。通过这样的预扣处理,可以保证不会出现超卖的情况。这个思路其实和传统电商比如淘宝这样的系统类似,我就不多展开了,我之前写的Conference案例也是这样的思路,大家有兴趣的可以去看一下我之前录制的视频。

查询余票的实现思路

我觉得余票的查询的实现相对简单。虽然对于12306来说,查询的请求占了80%,提交订单的请求只占20%。但查询由于对数据没有修改,所以我们完全可以使用分布式缓存来实现。我们只需要精心设计好缓存的key即可;缓存key的多少要看成本,如果所有可能的查询都设计对应的key,那时间复杂度为1,查询性能自然高;但代价也大,因为key多了。如果想key少一点,那查询的复杂度自然要上去一点。所以缓存设计无非就是空间换时间的思路。然后,缓存的更新无非就是:自动失效、定时更新、主动通知3种。通过CQRS架构,由于CQ两端是事件驱动的,当C端有任何状态变化,都会产生对应的事件去通知Q端,所以我们几乎可以做到Q端的准实时更新。

同时由于CQ两端的完全解耦,Q端我们可以设计多种存储,如数据库和缓存(Redis等);数据库用于线下维护关系型数据,缓存用户实时查询。数据库和缓存的更新速度相互不受影响,因为是并行的。对同一个事件,可以10台机器负责更新缓存,100台机器负责更新数据库。即便数据库的更新很慢,也不会影响缓存的更新进度。这就是CQRS架构的好处,CQ的架构完全不同,且我们随时可以重建一种新的Q端存储。不知道大家体会到了没有?

关于缓存key的设计,我觉得主要从查询余票时传递的信息来考虑。12306的关键查询是:出发地、目的地、出发日期三个信息。我觉得有两种key的设计思路:

1)直接设计了该查询条件的key,然后快速拿到车次信息,直接返回;这种方式就是要求我们系统已经枚举了所有车次的所有可能出现的票(区间)的缓存key,相信你一定知道这样的key是非常多的。

2)不是枚举所有区间,而是把每个车次的每个原子区间(相邻的两个站点所连成的直线)的可用票数作为key。这样,key就非常少了,因为车次假如有10000个,然后每个车次平均15个区间,那也就15W个key而已。

当我们要查询时,只需要把用户输入的出发地和目的地之间的所有原子区间的可用票数都查出来,然后比较出最小可用票数的那个原子区间。则这个原子区间的可用票数就是用户输入的区间的可用票数了。当然,到这里我提到考虑出发日期。我认为出发日期是用来决定具体是哪个车次聚合根的。同一个车次,不同的日期,对应的聚合根实例是不同的,即便是同一天,也可能有多个车次聚合根,因为有些车次一天有几班的,比如上午9点发车的一班,下午3点发车的一般。所以,我们也只要把日期也作为缓存key的一部分即可。

总结

本文完全是凭自己对12306这个网站的核心业务的简单思考而得到的一些设计结果。如果真正的DDD领域建模,更多的是要和业务一线的工作人员、领域专家进行深入沟通,才能更深入的了解该领域内的业务知识,从而才能设计出更靠谱的领域模型和架构设计。我本人非常惭愧因为没有上12306买过火车票,家离的比较近,就算要买也是家人给我买:)所以,本文所分享的内容难免是纸上谈兵。但我觉得12306这个系统的业务确实比传统的电商系统要复杂,且并发又这么高。所以,我觉得这个系统真的很值得大家重视模型的设计,而不只是只关注技术层面的实现。2016年,我有计划打算基于ENode实现一套12306的核心功能,比如余票查询、订票的功能。

注:相关网站建设技巧阅读请移步到建站教程频道。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读