`
zhanglu0223
  • 浏览: 22799 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

建设一个靠谱的火车票网上订购系统

 
阅读更多

建设一个靠谱的火车票网上订购系统

昨天,2012年1月11日,网友 @fenng 写了一篇文章,批评铁道部火车票网上订购系统,http://www.12306.cn[1]。同时在新浪发了一条言辞激烈的微博,“去你妈的‘海量事务高速处理系统’”,引起热议[2]

春节将到,大家买不着车票,赶不上大年三十与家人团聚,急切心情可以理解。但是拍桌子开骂,只能宣泄情绪,解决不了实际问题。

开发一套订票系统并不难,难在应对春运期间,日均 10 亿级别的洪峰流量。日均 10 亿级别的洪峰请求,在中国这个人口全球第一大国,不算稀罕,不仅火车票订票系统会遇到,而且电子商务在促销时,也会遇到,社交网站遇到新闻热点时,也会遇到。

所以,能够在中国成功运行的云计算系统,推广到全球,一定也能成功。但是在美国成功运行的云计算系统,移植到中国,却不一定成功。

如果我们能够设计建造一套,稳定而高效的铁路订票系统,不仅解决了中国老百姓的实际问题,而且在全球高科技业界,也是一大亮点,而且是贴着中国标签的前沿科技的亮点。

于是软件工程师们献计献策,讨论如何改进 12306 网上购票系统[3]。其中比较有代表性的,有两篇[4,5]

网友的评论中,有观点认为,[4] 利用“虚拟排队”的手段,将过程拉长负载降低,是网游的设计思路。而 [5] 利用缓存技术,一层层地降低系统负荷, 是互联网的设计思路。

个人认为,[4] 和 [5] 并不是相互排斥的两种路线,两者着重解决的问题不同,不妨结合起来使用,取长补短。下面介绍一下我们的设计草案,追求实用,摈弃花哨。抛砖引玉,欢迎拍砖。

图一。12306.cn 网站系统架构设想图。

Courtesyhttp://i879.photobucket.com/albums/ab351/kan_deng/12306.png

图一是系统架构图,典型的“展现层”/ “业务层”/ “数据层”的三段论。

用户接入有两类,一个是运行在电脑里的浏览器,例如 IE,另一个是手机。

无论用户用电脑浏览器,还是手机访问 http://www.12306.cn 网站,用户请求首先被网站的负载均衡器接收。负载均衡器连接着一群门户服务器,根据各个门户服务器的负载轻重,负载均衡器把用户请求,转发到某一相对清闲的门户服务器。

门户服务器的任务类似于收发室老头儿,它只读每个用户请求的前几个 bytes,目的是确定用户请求的类型,然后把请求投放到相应类型的队列中去。门户服务器的处理逻辑非常简单,这样做的好处,是让它能够快速处理大批量用户请求。

根据 [5] 的分析,12306 处理的用户请求,大致分为三类,

1. 查询。用户订票前,查询车次以及余票。用户下订单后,查询是否已经订上票。
2. 订票,包括确定车次和票数,然后付款。用户付款时,需要在网银等网站上操作。
3. 第一次访问的用户,需要登记,包括姓名和信用卡等信息。

三类请求的业务处理过程,被分为两个阶段,

1. 运行于缓存中的任务队列。设置队列的目的,是防止处理过程耗时太长,导致大量用户请求拥塞于门户服务器,导致系统瘫痪。

2. 业务处理处理器,对于每一类业务,分别有一群业务服务器。不同业务的处理流程,各不相同。

图二。12306.cn 网站查询和订票业务流程设想图。
Courtesyhttp://i879.photobucket.com/albums/ab351/kan_deng/12306-1.png

图二描述了查询和订票,两个业务的处理流程。登记业务流程从略。

查询的业务流程,参见图二上半部,分五步。这里有两个问题需要注意,

1. 用户发出请求后,经过短暂的等待时间,能够迅速看到结果。平均等待时间不能超过 1 秒。

2. 影响整个查询速度的关键,是“查询服务器”的设计。

查询任务可以进一步细化,大致分成三种。

1. 查询车次和时间表,这是静态内容,很少与数据库交互,数据量也不大,可以缓存在内存中。

车次和时间表的数据结构,不妨采用 Key-Value 的方式,开发简单,使用效率高。Key-Value 的具体实现有很多产品,[5] 建议使用 Redis。

这些是技术细节,不妨通过对比实验,针对火车票订票系统的实际流量,以及峰值波动,确定哪一个产品最合适。

2. 查询某一班次的剩余车票,这需要调用数据库中不断更新的数据。

[5] 建议把剩余车票只分为两种,“有”或“无”,这样减少调用访问数据库的次数,降低数据库的压力。但是这样做,不一定能够满足用户的需求,说不定会招致网友的批评讥讽。

[4] 建议在订票队列中,增加测算订票队列长度的功能,根据订票队列长度以及队列中每个请求的购票数量,可以计算出每个车次的剩余座位。如果 12306.cn 网站只有一个后台系统,这个办法行之有效。

但是假如 12306.cn 网站采用分布式结构,每个铁路分局设有子系统,分别管理各个铁路分局辖区内的各个车次。在分布式系统下,这个办法面临任务转发的麻烦。不仅开发工作量大,而且会延长查询流程处理时间,导致用户长久等待。

3. 已经下单的用户,查询是否已经成功地订上票。

每个用户通常只关心自己订的票。如果把每个用户订购的车票的所有内容,都缓存在内存里,不仅非常耗用内存空间,内存空间使用效率低下,更严重的问题是,访问数据库过于频繁,数据量大,增大数据库的压力。

解决上述分布式同步,以及数据库压力的两个问题,不妨从订票的流程设计和数据结构设计入手。

假如有个北京用户在网上订购了一套联票,途经北京铁路局和郑州铁路局辖区的两个车次。用户从北京上网,由北京铁路局的子系统,处理他的请求。北京铁路局的订票服务器把他的请求一分为二,北京铁路局的车次的订票,在北京子系统完成,郑州铁路局的车次在郑州子系统完成。

每个子系统处理四种 Key-Value 数据组。

1. 用户ID:多个 (订单ID)s。
2. 订单ID:多个 (订票结果ID)s。
3. 订票结果ID: 一个 (用户ID,车次ID)。
4. 车次ID:一个(日期),多个 (座位,用户ID)。

北京订票服务器完成订票后,把上述四个数据组,写入北京子系统的数据库,同时缓存进北京的查询服务器,参见图二下半部第6步和第7步。

郑州订票服务器完成订票后,把上述四个数据组,写入郑州子系统的数据库,同时缓存进北京的查询服务器,而不是郑州的服务器。

让订票服务器把订票数据,同时写入数据库和查询服务器的缓存,目的是让数据库永久保留订票记录,而让大多数查询,只访问缓存,降低数据库的压力。

北京用户的订票数据,只缓存在北京的查询服务器,不跨域缓存,从而降低缓存空间的占用,和同步的麻烦。这样做,有个前提假设,查询用户与订票用户,基本上是同一个人,而且从同一个城市上网。

但是这里有个缺陷,某用户在北京上网订了票。过了几天,他在北京上网,输入用户ID和密码后,就会看到他订购的所有车票。可是又过了几天,他去了郑州,从郑州上网,同样输入用户ID和密码,却看不到他订购的所有车票。

解决这个缺陷的办法并不麻烦,在用户查询订票信息时,需要注明订票地点,系统根据订票地点,把查询请求转发到相应区域的子系统。

另外,每次订票的时候,网站会给他的手机发送短信,提供订票信息,参见图二下半部第8步和第9步。

以上是一个初步设计,还有不少细节需要完善,例如防火墙如何布置等等。这个设计不仅适用于单一的集中式部署,而且也适合分布式部署。

或许有读者会问,为什么没有用到云计算?其实上述架构设计,为将来向云计算演变,留下了伏笔。

在上述架构设计中,我们假定每个环节需要用多少服务器,需要多大容量的数据库,预先都已经规划好。但是假如事先的规划,低于实际承受的流量和数据量,那么系统就会崩溃。所以,事先的规划,只能以峰值为基准设立。

但是峰值将会是多少?事先难以确定。即便能够确定峰值,然后以峰值为基准,规划系统的能力,那么春运过后,就会有大量资源冗余,造成资源浪费?

如何既能抗洪,又不造成资源浪费?解决方案是云计算,而且目前看来,除了云计算,没有别的办法。

Reference,

[1] 海量事务高速处理系统。

http://www.douban.com/note/195179318/

[2] 去你妈的‘海量事务高速处理系统’。

http://weibo.com/1577826897/y0jGYcZfW

[3] 火车订票系统的设想。

http://weibo.com/1570303725/y0l9Y2mwE

[4] 铁路订票系统的简单设计。

http://blog.codingnow.com/2012/01/ticket_queue.html

[5] 铁路订票网站个人的设计浅见。

http://hi.baidu.com/caoz/blog/item/f4f1d7caee09b558f21fe780.html

题图来自Designyoutrust

分享到:
评论

相关推荐

    建设一个靠谱的火车票网上订购系统.pdf

    ### 建设一个靠谱的火车票网上订购系统——关键技术解析 #### 一、背景介绍 随着信息技术的发展,网络已成为人们生活中不可或缺的一部分。特别是在中国这样一个庞大的国家,每年春节期间都会有数以亿计的人口流动,...

    招聘一个靠谱ios面试题答案(下)

    10. 在不手动指定autoreleasePool的情况下,一个autoreleased对象会在当前Runloop迭代结束后、进入下一个迭代前或者Runloop终止时释放。 11. BAD_ACCESS错误通常发生在尝试访问已经被释放的对象时。 12. 苹果通过...

    《做一个靠谱的人》心得体会.pdf

    在阅读《做一个靠谱的人》后,我对靠谱这个词的含义有了更深的理解。靠谱并不仅仅是对他人的承诺,更是对自己生活态度的一种体现。靠谱的人是那些能够承担起责任,无论面对何种困难,都能坚持到底,以实际行动展现出...

    靠谱助手微信版

    总的来说,靠谱助手微信版是一个强大的安卓模拟器,它不仅让微信在电脑上的使用更加高效,还为用户打开了一个全新的安卓应用世界。其强大的功能、广泛的软件库以及对微信的良好支持,使得它成为许多用户在桌面端使用...

    金融企业安全建设探索之靠谱的安全人员.pdf

    金融企业安全建设探索之靠谱的安全人员 移动安全 区块链 端点安全 安全分析 安全分析

    学生综合靠谱管理系统JAVA源代码

    【标题】中的“学生综合靠谱管理系统JAVA源代码”指出,这是一个使用Java编程语言开发的学生管理系统的源代码。在IT行业中,源代码是程序设计的基础,它由程序员编写,用于控制软件的行为。Java是一种广泛使用的面向...

    怎样构建靠谱团队

    总之,构建靠谱的IT团队是一个系统工程,涉及到目标设定、人员选拔、工具利用、培训发展、环境营造等多个方面。只有全面考虑并实施这些策略,才能打造出一支既专业又高效的团队,以应对日益复杂和快速变化的IT挑战。

    靠谱助手1.4

    总的来说,靠谱助手1.4是一个强大的工具,它让手机游戏在电脑上的体验更加便捷和舒适,同时也提供了更多的功能性扩展,满足用户多样化的需求。无论是为了享受高清大屏的游戏体验,还是为了高效的工作应用,靠谱助手...

    面试总结js 靠谱靠谱靠谱.md

    面试总结js 靠谱靠谱靠谱.md

    下载靠谱助手吧

    安卓模拟器社区(靠谱社区)是中国最大的安卓模拟器交流论坛,下载靠谱助手安卓模拟器可在PC电脑上极速运行安卓手游和应用。最全手机游戏电脑版攻略心得!

    财务开票管理系统

    综上所述,财务开票管理系统是一款结合了先进技术和管理理念的软件产品。它不仅解决了传统财务工作中存在的诸多问题,还为企业提供了更为全面、高效的财务管理解决方案。通过上述详细介绍可以看出,该系统在设计时...

    靠谱的文件切割工具

    在提供的资源中,包含了两个这样的工具,一个是作者的同学编写的,尽管简单,但其可靠性得到了保证;另一个则是从网络上找到的,同样具有良好的实用性和易用性。这两种工具都附带了使用说明,用户可以按照说明进行...

    2019商场“不靠谱”菜馆主题活动策划方案【餐饮】【活动策划】.rar

    标题"2019商场“不靠谱”菜馆主题活动策划方案【餐饮】【活动策划】.rar"表明这是一个关于2019年在商场内针对一家名为“不靠谱”菜馆的特殊主题活动的策划方案。该方案可能包含了一系列创新的营销策略和活动设计,...

    双鱼林JSP基于SSH2教务选课成绩管理系统.zip_SSH教务管理系统源码_双鱼林 教务_双鱼林靠谱吗_教务系统_选课

    双鱼林JSP基于SSH2的教务选课成绩管理系统是一个综合性的教务管理平台,主要服务于学生和教师,提供在线选课、成绩查询等多种功能。SSH2是Struts2、Spring和Hibernate三个开源框架的集成,它们在Java Web开发中扮演...

    ChatGPT的10个靠谱用法

    作为一个聊天机器人系统,这家伙可以说是太会聊天了。ChatGPT可以根据用户的兴趣、爱好、习惯等,生成个性化的聊天内容,与用户进行有趣的对话。 只是别太要求信息的可靠度,你就当作和人类在聊天呗,哪有100%可靠...

    靠谱助手安卓PC模拟器

    靠谱助手安卓PC模拟器

    读《马克思靠谱》心得.pdf

    读《马克思靠谱》心得.pdf

    《招聘一个靠谱的iOS》面试题参考答案(上).md

    ### 招聘一个靠谱的iOS开发者:面试题参考答案(上) #### 一、简历的重要性及注意事项 在招聘过程中,一份优秀的简历至关重要。它不仅能够展现应聘者的专业能力和项目经验,还能体现其个人品质与职业态度。对于...

    读《马克思靠谱》心得参考.doc

    读《马克思靠谱》心得参考.doc

    靠谱助手V3.5.2247_setup

    靠谱手机安卓应用助手,海量应用随便下载,实用、好用。

Global site tag (gtag.js) - Google Analytics