12306核心模型设计思路和架构设计缓存
技术人员每每更注重技术层面的解决方案,好比一上来就分析如何集群、负载均衡、排队、分库分表、用锁,用缓存等技术问题,而忽略了最根本的业务层面的思考,如分析业务、领域建模。其实复杂的业务系统,则越要设计一个健壮的领域模型。若是一个系统的架构咱们设计错了,还有补救的余地,由于架构最终沉淀的只是代码,调整架构便可;而若是领域模型设计错了,那要补救的代价是很是大的,由于领域模型沉淀的是数据结构及其对应的大量数据,对任何一个大型系统,要改核心领域模型都是成本很是高的。数据结构
12306这个系统,核心要解决的问题是网上售票。涉及到2个角色使用该系统:用户、铁道部。用户的核心诉求是查询余票、购票;铁道部的核心诉求是售票。购票和售票实际上是一个场景,对用户来讲是购票,对铁道部来讲是售票。所以,咱们要设计一个在线的网站系统,解决用户的查询余票、购票,以及铁道部的售票这3个核心诉求。看起来,这3个场景都是围绕火车票展开的。最主要的需求就是查询余票和购票。架构
其实能够将12306类比成一个商品是车票的电商系统,那购票就相似于购买商品,而后每张票都有库存,商品也有库存的概念。可是若是咱们仔细想一想,会发现12306要复杂不少,由于咱们没法预先肯定好全部的票,若是非要肯定,那只能经过穷举法了,实际上,这个车次能够卖的票是很是多的。为了方便后面的讨论,咱们先明确一下票是什么?经过分析,咱们能够知道一张票的本质是某个车次的某一段区间(一条线段),这个区间包含了若干个站点。而后咱们还发现,只要区间不重叠,那座位就不会发生竞争,能够被回收利用,也就是说,能够同时预先出售。另外,通过更深刻的分析,咱们还发现区间有4种关系;不重叠部分重叠、彻底重叠、覆盖,不重叠的状况咱们已经讨论过了,而覆盖也是重叠的一种。因此咱们发现若是重叠,好比有两个区间发生重叠,那重叠部分的区间(可能夸一个或多个站点)是在争抢座位的。由于假设一列火车有100个座位,那每一个原子区间(两个相邻站点的连线),最多容许重叠99次。一个车次可以出售一张车票的核心业务规则是这张车票所包含的每一个原子区间的重叠次数加1都不能超过车次的总座位数,实际上重叠次数+1也能够理解为线段的厚度。负载均衡
GRASP九大模式中的信息专家模式,将职责分配给拥有执行该职责所需信息的类。咱们这个场景,车次具备一次出票的全部信息,因此咱们应该把出票的职责交给车次。DDD中聚合设计有一个原则,就是:聚合内强一致性,聚合之间最终一致性。票不是核心聚合根,票只是一个计算的结果,一个凭证而已,票自己没有什么逻辑;12306真正的核心模型应该是车次,车次具备出票的职责,并以强一致性的方式维护一次出票(或退票)时全部原子区间的可用票数。2306这样的业务场景,很是适合使用CQRS架构;由于首先它是一个查多写少、可是写的业务逻辑很是复杂的系统。因此,很是适合作架构层面的读写分离,即采用CQRS架构网站