火车订票网站建设(火车票订购网站是什么)

企业建站 1
本文目录一览: 1、越南火车票订票网站是哪个? 2、浅论12306网上购票系统的设计

本文目录一览:

越南火车票订票网站是哪个?

2014年,越南政府花巨资建设了一个类似于我们12306的火车票购买网站,体验这种米轨铁路特殊的感受,突然成为很多人独特的追求,而我,便是其中的一个。

2014年以前,旅行者们只能通过三种途径购买越南火车票:第一种是到了当地再到车站窗口购买,不过由于越南尚未实行车票实名制,火车票经常被票贩子抢去大半,这样便会存在买不到票的风险;第二种是找车站附近的旅行社购买,他们是囤票的主力军,但是价格完全不透明,有被坑的风险;第三种是找万能的淘宝代购,一般也是中国的旅行社帮忙购买,按照每张票加收50元的费用购买,这个手续费显然非常高。

自从越南火车购票官方网站 出世之后,一切都变得简单了很多。进入界面之后,第一反应肯定是傻眼了,全是越南语,另外,上面的宣传图片有没有把你带回九十年代呢?为了保证购买顺利(主要是在支付阶段出问题),建议fan qiang之后再登陆网站。

浅论12306网上购票系统的设计

12306可以说是一个成功型的案例。

你对他不好的印象是来自于12306刚出来那年,抢火车票导致各种崩溃,加载不出来,特别难辨认的验证码,还要安装什么安全的证书。

后来几年12306做了重大的底层技术变革,但是网页UI并没有换(关于UI这个东西,更换UI对用户来说是有学习代价的,尤其12306是一款面相全国人民的网页和app,UI是不能随便换的)

所以你就会理所当然的认为现在的12306还是以前的12306,非也,现在的12306每天能扛得住30亿次查询请求。

通过官方的网页、铁路12306 app、携程、去哪儿、超级火车票,还有各种民间程序员写的抢票工具等等,包括各种浏览器插件不停的刷新抢票。还有人嫌弃自己不是下铺,也要刷刷刷,改成满意的为止。

有一张火车票被退了,其实这张票只是一个区间,比如西安始发,到北京终点这张票被退了,这样按道理来说中间任意经停站到任意经停站都可以买票,等等,会有很多意想不到的需求,包含各种奇葩的组合

综上所述,其实12306的业务逻辑远比淘宝这样的电商要复杂很多

需求分析、系统设计不仅要考虑到全国各省的情况,还要考虑窗口买票,电话买票不受互联网购票的影响。

毕竟在窗口查出一张票,在用户决定买它之前,这张票不可能被互联网购票的人给抢了。也就是说互联网购票在票源稀缺的情况下,和窗口电话购票相比是没有优势的。

互联网购票之所以会失去优势,主要原因就是12306购票系统为了支持每天大量的查询请求,把票数的缓存时间调整的极长,笔者目测可能5分钟都不止。

简单说就是现在西安去北京的票是0张,突然有人退了票,这时2个人,一个窗口订票,一个互联网订票。

互联网订票的人刷新发现还是0张,当然他也是不停地刷新,但是得到的是旧的缓存信息

窗口订票的人花了5分钟时间排队,等到他的时候,互联网订票的人刷新出来了一张余票,他点击购买,选乘坐人,提交订单的时候,窗口排队的人也在售票员那里查到了一张余票,这时候互联网订票者提交的订单会失败,窗口订票的人会成功买到这张宝贵的票源。

然而这个故事还没有结束。在窗口购票的那个人开心的拿着自己的票走了之后,互联网购票的人回到票源查询界面刷新发现还是有一张余票,他看到的还是旧的缓存,点击票源会收到不是最新票源的提示,直到5分钟之后,票源会再次变为0。

简单的来说,12606就是这样设计的,从此春运再多人抢票也不会导致网站直接崩溃,大不了就是余票为0喽。

参考资料:

火车售票系统数据库设计(请详细说一下具体包含哪些表)

包含的表主要有

列车(列车编号,车种,始发站,始发站,终到站,发时,到时,里程)

车站(车站id,车站名)

经过(列车编号,车站名,站次,里程,到时,发时)

车票(车票编号,车次,发站,到站,发站次,到站次,发时,到时,座位类型,座位号,车票日期,票价)

主要是这四个表,查询插入操作有些复杂不过都能完成

详细看列车票务系统数据库课程设计说明书,文库里有

旅游网站建设的后台功能有哪些?

对于前台:以雅观、大方的界面,直观、图文相间的页面面对浏览者,以简略的操作让浏览者完成预订,并供给了多种咨询和交流路径,将贵社的联系信息在页面中多次显示等尽最大的有可能让浏览者都酿成您的客户,从而带来经济效益。 对于后台:强大的功能,清晰的结构,简化的界面,方便您操作办理,节省您的工作时间。旅游旅行社网站办理系统,全站步伐领有的强大的功能,成熟的代码编写,标致的担任美术工作的人,是自助旅游网站建设,最佳终极选择,最后帮助旅行社扩大网上营业。旅游旅行社网站办理系统前台办理功能列表。 旅行社网站必需有的旅游线路预订,宾馆旅店预订,火车票预订,飞机票预订,旅游租车预订几大功能,是旅行社网站的核心内容。 旅游旅行社办理系统,如关于我社,具体介绍旅行社,最新动态发布有旅行社的最新旅游动态新闻,旅游预订线路,为旅行社网站使成为事实电子商务化的重要功能,全后台添加办理旅游线路预订,线路搜索是网站步伐方便旅客搜索旅游线路同时旅店预先规定系统,具体介绍旅行社合作的宾馆旅店具体情况,并方便旅客在网上远程预订. 旅行社票务系统,有飞机票,火车票预订,使成为事实网站电子售票对外租赁车,自驾车使成为事实展示,预订旅行社的租车营业,有旅行社所推出的旅游线路各个景色的具体介绍,图文并茂,使旅客,在网站提前相识赏识,旅客在旅游中选择,为旅行社潜在旅客留言,回复相干旅游事宜综合查询,查询旅行社整站的旅行线路搜索,宾馆旅店搜索,火车票搜索,飞机票搜索网站站内短信,是旅客和旅行社网站办理员,即时沟通的有效工具。 以上网站功能,全部使成为实施后台办理控制,整个旅行社旅游营业方便更新旅游线路的添加,线路编辑,删除旅游线路宾馆旅店的添加删除,导游,胜地,旅游旅行社新闻动态办理,留言本办理,投票设置,修改,站内短信查看订单查看与系统设置有,线路订单,旅店订单,飞机票订单,火车票订单,旅游租车订单,后台登陆密码修改等。

铁路订票的官方网站是什么?

铁路订票的官方网站是铁路客户服务中心网站(),即12306网站。2010年8月8日,铁路部门人士透露,铁道部目前正在建设正式的订票网,顺利的话可能会在年内开通。 2009年春运时,铁道部曾开通网络服务中心,旅客可查询火车票余票信息,每小时更新一次。与以往只可到售票窗口询问或到车站大屏幕上看余票显示相比,此举为旅客了解车票信息、安排行程提供了便利。 自2012年春运开始,铁路客票的发售开始“三管齐下”,由实名制购票、互联网订票和电话订票组成。

不就是一个订票网站吗,12306的核心模型设计思路究竟复杂在哪儿

12306这个系统,核心要解决的问题是网上售票。涉及到2个角色使用该系统:用户、铁道部。用户的核心诉求是查询余票、购票;铁道部的核心诉求是 售票。购票和售票其实是一个场景,对用户来说是购票,对铁道部来说是售票。因此,我们要设计一个在线的网站系统,解决用户的查询余票、购票,以及铁道部的 售票这3个核心诉求。看起来,这3个场景都是围绕火车票展开的。

查询余票:用户输入出发地、目的地、出发日三个条件,查询可能存在的车次,用户可以看到每个车次经过的站点名称,以及每种座位的余票数量。

购票:购票分为订票和付款两个阶段,本文重点分析订票的模型设计和实现思路。

其实还有很多其他的需求,比如给不同的车次设定销售座位数配额,以及不同的区段设置不同的限额。但相比前面两个需求来说,我觉得这个需求相对次要一些。

需求分析

确实,12306也是一个电商系统,而且看起来商品就是票了。因为如果把一张票看成是一个商品,那购票就类似于购买商品,然后每张票都有库存,商品 也有库存的概念。但是如果我们仔细想想,会发现12306要复杂很多,因为我们无法预先确定好所有的票,如果非要确定,那只能通过穷举法了。

我们以北京西到深圳北的G71车次高铁为例(这里只考虑南下的方向,不考虑深圳北到北京西的,那是另外一个车次,叫G72),它有17个站(北京西 是01号站,深圳北是17号站),3种座位(商务、一等、二等)。表面看起来,这不就是3个商品吗?G71商务座、G71一等座、G71二等座。大部分轻 易喷12306的技术人员(包括某些中等规模公司的专家、CTO)就是在这里栽第一个跟头的。实际上,G71有136*3=408种商品(408个 SKU),怎么算来的?如下:

如果卖北京西始发的,有16种卖法(因为后面有16个站),北京西到:保定、石家庄、郑州、武汉、长沙、广州、虎门、深圳。。。。都是一个独立的商 品,同理,石家庄上车的,有15种下车的可能,以此类推,单以上下车的站来计算,有136种票:16+15+14….+2+1=136。每种票都有3种座 位,一共是408个商品。

为了方便后面的讨论,我们先明确一下票是什么?

一张票的核心信息包括:出发时间、出发地、目的地、车次、座位号。持有票的人就拥有了一个凭证,该凭证表示持有它的人可以坐某个车次的某个座位号, 从某地到某地。所以,一张票,对用户来说是一个凭证,对铁道部来说是一个承诺;那对系统来说是什么呢?不知道。这就是我们要分析业务,领域建模的原因,我 们再继续思考吧。

明白了票的核心信息后,我们再看看G71这个车次的高铁,可以卖多少张票?

讨论前先说明一下,一辆火车的物理座位数(站票也可以看成是一种座位,因为站票也有数量配额)不等于可用的最大配合。所有的物理座位不可能都通过 12306网站来销售,而是只会销售一部分,比如40%。其余的还是会通过线下的方式销售。不仅如此,可能有些站点上车的人会比较多,有些比较少,所以我 们还会给不同的区间配置不同的限额。比如D31 北京南至上海共有765张,北京南有260张,杨柳青有80张,泰安有76张。如果杨柳青的80张票售完就会显示无票,就算其他站有票也会显示无票的。每 个车次肯定会有各种座位的配额和限额的配置的,这种配置我目前无法预料,但我已经把这些规则都封装近车次聚合根里了,所有的配置策略都是基于座位类型、站 点、区间配置的。关于票的配置抽象出来,我觉得主要有3种:1)某个区段最多允许出多少张;2)某个区段最少允许出多少张;3)某个站点上车的最多多少 张;当用户订票时,把用户指定的区段和这3种配置条件进行比较,3个条件都满足,则可以出票。不满足,则认为无票了。下面举个例子:

ABCDEFG,这是所有站点。座位总配额是100,假设B站点上车,E站下车的人比较少,那我们就可以设定BE这个区段最多只能出10张票。所 以,只要是用户的订票是在这个区段内的,就最多出10张。再比如,一列车次,总共100个座位配额,希望全程票最少满足80张,那我们只要给AG这个区段 设定最少80张。那任何订票请求,如果是子区间的,就不能超过100-80,即20张。这两种条件必须同时满足,才允许出票。

但是,不管如何做配额和限额,我们总是针对某个车次进行配置,这些配置只是车次内部售票时的一些额外的判断条件(业务规则),不影响车次模型的核心 地位和对外暴露的功能。所以,为了本文讨论的清楚起见,我后续的讨论都不涉及配额和限额的问题,而是认为任何区段都可以享受火车最大的物理座位数。

并且,为了讨论问题方便,我们减少一些站点来讨论。假设某个车次有A,B,C,D四个站点。那001这个人购买了A,B这个区间,系统会分配给 001一个座位x;但是因为001坐到B站点后会下车,所以相当于x这个座位又空出来了,也就是说,从B站点开始,系统又可以认为x这个座位是可用的。所 以,我们得出结论:同一个座位,其实可以同时出售AB,BC这两张票。通过这个简单的分析,我们知道,一列火车虽然只有有限的座位数,比如1000个座 位。但可以卖出的票远远不止1000个。还是以A,B,C,D四个站点为例,假如火车总共有1000个座位,那AB可以卖1000张,BC也可以卖 1000张,同样,CD也可以卖1000张。也就是说,理论上最多可以卖出3000张票。但是如果换一种卖法,所有人都是买ABCD的票,也就是说所有的 票都是经过所有站点的,那就是最多只能卖出1000张票了。而实际的场景,一定是介于1000到3000之间。然后实际的G71这个车次,有17个站,那 到底可以卖出多少个票,大家应该可以算了吧。理论上这17个站中的任意两个站点之间所形成的线段,都可以出售为一张票。我数学不好,算不太清楚,麻烦有数 学好的人帮我算算,呵呵。

通过上面的分析,我们知道一张票的本质是某个车次的某一段区间(一条线段),这个区间包含了若干个站点。然后我们还发现,只要区间不重叠,那座位就不会发生竞争,可以被回收利用,也就是说,可以同时预先出售。

另外,经过更深入的分析,我们还发现区间有4种关系:1)不重叠;2)部分重叠;3)完全重叠;4)覆盖;不重叠的情况我们已经讨论过了,而覆盖也 是重叠的一种。所以我们发现如果重叠,比如有两个区间发生重叠,那重叠部分的区间(可能夸一个或多个站点)是在争抢座位的。因为假设一列火车有100个座 位,那每个原子区间(两个相邻站点的连线),最多允许重叠99次。

所以,经过上面的分析,我们知道了一个车次能够出售一张车票的核心业务规则是什么?就是:这张车票所包含的每个原子区间的重叠次数加1都不能超过车次的总座位数,实际上重叠次数+1也可以理解为线段的厚度。

模型设计

上面我分析了一下票的本质是什么。那接下来我们再来看看怎么设计模型,来快速实现购票的需求,重点是怎么设计商品聚合以及减库存的逻辑。

传统电商的思路

如果按照普通电商的思路,把票(站点区间)设计为商品(聚合根),然后为票设计库存数量。我个人觉得是很糟糕的。因为一方面这种聚合根非常多(上面 的G71就有408个);另一方面,即便枚举出来了,一次购票也一定会影响非常多其他聚合根的库存数量(只要被部分或全部重叠的区间都受影响)。这样的一 次订单处理的复杂度是难以评估的。而且这么多聚合根的更新要在一个事务里,这不是为难数据库吗?而且,这种设计必然带来大量的事务的并发冲突,很可能导致 数据库死锁。总之,我认为这种是典型的由于领域模型的设计错误,导致并发冲突高、数据持久化落地困难。或者如果要解决并发问题,只能排队单线程处理,但是 仍然解决不了要在一个事务里修改大量聚合根的尴尬局面。听说12306是采用了Pivotal Gemfire这种高大上的内存数据库,我对这个不太了解。我不可想象要是不使用内存数据库,他们要怎么实现车次内的票之间的数据强一致性(就是保证所有 出售的票都是符合上面讨论的业务规则的)?所以,这种设计,我个人认为是思维定势了,把火车票看成是普通电商的商品来看待。所以,我们有时做设计又要依赖 于经验,又要不能被以往经验所束缚,真的不容易,关键还是要根据具体的业务场景多多深入分析,尽量分析抽象出问题的本质出来,这样才能对症下药。那是否有 其他的设计思路呢?

我的思路

聚合设计

通过上面的分析我们知道,其实任何一次购票都是针对某个车次的,我认为车次是负责处理订票的聚合根。我们看看一 个车次包含了哪些信息?一个车次包括了:1)车次名称,如G71;2)座位数,实际座位数会分类型,比如商务座20个,一等座200个;二等座500个; 我们这里为了简化问题,可以暂时忽略类型,我认为这个类型不影响核心的模型的设计决策。需要格外注意的是:这里的座位数不要理解为真实的物理座位数,很有 可能比真实的座位数要少。因为我们不可能把一个车次的所有座位都在网上通过12306来出售,而是只出售一部分,具体出售多少,要由工作人员人工指定。 3)经过的站点信息(包括站点的ID、站点名称等),注意:车次还会记录这些站点之间的顺序关系;4)出发时间;看过GRASP九大模式中的信息专家模式的同学应该知道,将职责分配给拥有执行该职责所需信息的类。我们这个场景,车次具有一次出票的所有信息,所以我们应该把出票的职责交给车次。另外学过DDD的同学应该知道,聚合设计有一个原则,就是:聚合内强一致性,聚合之间最终一致性。经 过上面的分析,我们知道要产生一张票,其实要影响很多和这个票对应的线段相交的其他票的可用数量。因为所有的站点信息都在车次聚合内部,所以车次聚合内部 自然可以维护所有的原子区间,以及每个原子区间的可用票数(相当于是库存数)。当一个原子区间的可用票数为0的时候,意味着火车针对这个区间的票已经卖完 了。所以,我们完全可以让车次这个聚合根来保证出票时对所有原子区间的可用票数的更新的强一致性。对于车次聚合根来说,这很简单,因为只是几次简单的内存 操作而已,耗时可以忽略。一列火车假如有ABCD四个站点,那原子区间就是3个。对于G71,则是16个。

怎么判断是否能出票

基于上面的聚合设计,出票时扣减库存的逻辑是:

根据订单信息,拿到出发地和目的地,然后获取这段区间里的所有的原子区间。然后尝试将每个原子区间的可用票数减1,如果所有的原子区间都够减,则购 票成功;否则购票失败,提示用户该票已经卖完了。是不是很简单呢?知道了出票的逻辑,那退票的逻辑也就很简单了,就是把这个票的所有原子区间的可用票数加 1就OK了。如果我们从线段的厚度的角度去考虑,那出票时,每个原子区间的厚度就是+1,退票时就是减一。就是相反的操作,但本质是一样的。

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

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

如何为票分配座位

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

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

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

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

假设现在的情况是座位有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已经有人了。而通过优先回收利用的算法,是没这个问题的。

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

模型分析总结

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

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

判断是否可出票;

选择可用的座位;

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

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

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

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

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

架构设计(非本文重点,没兴趣的朋友可以略过)

我觉得12306这样的业务场景,非常适合使用CQRS架构;因为首先它是一个查多写少、但是写的业务逻辑非常复杂的系统。所以,非常适合做架构层面的读写分离,即采用CQRS架构。而且应该使用数据存储也分离的CQRS。这样CQ两端才可以完全不需要顾及对方的问题,各自优化自己的问题即可。我们可以在C端使用DDD领域模型的思路,用良好设计的领域模型实现复杂的业务规则和业务逻辑。而Q端则使用分布式缓存方案,实现可伸缩的查询能力。

订票的实现思路

同时借助像ENode这样的框架,我们可以实现in-memory + Event Sourcing的架构。Event Sourcing技术,可以让领域模型的所有状态修改的持久化统一起来,本来要用ORM的方式保存聚合根最新状态的,现在只需要简单的通用的方式保存一个 事件即可(一次订票只涉及一个车次聚合根的修改,修改只产生一个事件,只需要持久化一个事件(一个JSON串)即可,保证了高性能,无须依赖事务,而且通 过ENode可以解决并发问题)。我们只要保存了聚合根每次变化的事件(事件的结构怎么设计,本文不做多的介绍了,大家可以思考下),就相当于保存了聚合 根的最新状态。而正是由于Event Sourcing技术的引入,让我们的模型可以一直存活在内存中,即可以使用in-memory技术。不要小看in-memory技术,in- memory技术在某些方面对提高命令的处理性能非常有帮助。比如就以我们车次聚合根处理出票的逻辑,假设某个车次有大量的命令发送到分布式消息队列,然 后有一台机器订阅了这个队列的消息,然后这台机器处理这个车次的订票命令时,由于这个车次聚合根一直在内存,所以就省去了每次要去数据库取出聚合根的步 骤,相当于少了一次数据库IO。这样的好处是,因为一个车次能够真正出售的票是有限的,因为座位就那么几个,比如就1000个座位,估计一般正常情况也就 出个2000个左右的票吧(具体能出多少张票要取决于区间的相交程度,上面分析过)。也就是说,这个聚合根只会产生2000个事件,也就是说只会有 2000个订票命令的处理是会产生事件,并持久化事件;而其余的大量命令,因为车次在内存计算后发现没有余票了,就不会做任何修改,也不会产生领域事件, 这样就可以直接处理下一个订票命令了。这样就可以大大提高处理订票命令的性能。

另外一个问题我觉得还需要提一下,因为用户订票成功后,还需要付款。但用户有可能不去付款或者没有在规定的时间内完成付款。那这种情况下,系统会自 动释放该用户之前订购的票。所以基于这样的需求,我们在业务上需要支持业务级别的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 的一部分即可。

火车订票网站建设 火车票订购网站是什么火车订票系统火车购票网站火车票预订网站数据库设计订火车票网址火车票网上订票网址在线订火车票系统火车订票系统活动图火车票 网站火车票的订购网站
扫码二维码