社区专家谈12306

由于春运,铁道部官方订票网站12306流量暴增,其Alexa排名一度进入前200,网友戏称,12306已经成为“全球最大、最牛的电商网站”。由于流量激增,12306系统频频瘫痪,一度出现登不上去、登上去抢不了票、抢到票需排队、排队后出票失败等局面。系统的用户体验、性能遭到用户大量的不满。 

我们邀请了几位系统架构方面的专家,请他们从技术的角度为你剖析12306(我们会陆续增加其他几位专家的回复)。同时我们还从论坛活动(畅聊12306,赢精美礼品)中选取了一些精彩回复。如果您对这些问题有独到的见解,欢迎在本文中评论或参与论坛讨论。

范凯   写道

春运和国庆期间没有买过。但去年夏天在12306上面买过票,结果没有买到票,改买了飞机票。 
我只用过一次,体验不深。感觉系统不太稳定,我访问的时候看到过Java出错抛出的错误堆栈信息。

陈雄华   写道
有。界面很象是企业MIS,显得很粗糙,交互性,体验性都感觉很次。

runfriends(来自论坛回复) 写道
我知道它很难用,所以我从来没用它买过票。去年国庆节查询个票,慢的要命。 
从sql的拼写到页面优化,从程序架构到服务器架构都需要全面重构。居然不是参数化查询sql,而是查询参数拼到sql里的,完全是一群业余选手的习作。  
应该采用js、css、图片、html都应该启用gzip压缩,所有css应减少到一个,js文件该合并的合并,能重用的重用,页面背景图应尽量合并成一个文件。尽量减少http请求数。


范凯    写道

对具体情况我不太了解。我猜测,实时购票是一个高并发的在线事务处理系统,需要通过排队系统来缓解事务并发造成的锁定吧。

陈雄华    写道
排队是缓解资源并发的一次不错的策略,可以在后端资源不足时,将客户端请求暂存在池中,方便系统资源的调度。

runfriends(来自论坛回复) 写道
刚开始的时候看到网上很多人说它有一个巨大的事务。后来又加入了排队系统。至于为什么个人猜测可能是为了降低数据库压力。 
而实际上,用户并发量并没有变化,排队导致大量访问不能尽快返回,占用了大量系统资源。实际上这样做降低了系统吞吐量。数据库压力有没有降低先不说,系统吞吐量肯定会降低。

czwlucky(来自论坛回复) 写道
我认为增加这个功能的意义在于,当你不能立即买上票时,不用再不停的反复刷新提交了,相当于银行里发给你一个“号码”,等叫你时你过来买票就是了,不用站那儿傻等。一方面增强了用户体验感,另一方面也能节约反复请求带来的压力。 
但我认为买票难根本原因不在于这个,12306网站的压力自然是大的,但这表面的背后却隐藏着更多的问题,为什么一票难求? 我们问自己一个问题:究竟一列火车有多少张票可卖? 你会发现没有答案! 如果真的没有答案,那即便你把12306刷到爆,也无济于事。 
所以我认为,在系统设计上不是问题,像淘宝、天猫一样有大量的访问者,解决方案也不是就一个。 问题还是在于业务的设计上,只有把出票规则定合理了,系统才能更好的为大家服务,我们也不用去刷网站了,压力自然也会因此而小一些。 
无论是从新闻上了解的,还是我亲身经历的,都证明从始点站开始买票会相对容易些,因为开始出票时,票数还是较多的(虽然也不是很多,大家都似懂非懂的),但从中间站点开始买票,票数少的可怜,甚至是0(网络延迟造成的)。这里面有一个二次售票的概念,怎么把这个二次售票的问题解决了才可能改善购票难问题。 
二次售票我相信有它存在的理由。 但问题时它存在的理由真的注定它只能是现在这样的方式存在吗? 我也相信这个业务规则一定有改进的地方。 
公交车,火车,长途汽车,在售票方式与运输距离,输送量上有很大差别,但运输本质没有差异。我们是不是能参考公交运输中的一些优点呢?比如是不是有可能增加同一线路的车次? 如果不能增加车次,是不是可以考虑沿途换乘方案?

范凯    写道

相同之处应该都是高并发的在线事务处理系统,我猜测主要不同之处在于12306背后的票务系统可能不是一个集中式的系统,而可能连接各个铁路局票务系统,数据同步的实时性和一致性可能更复杂一些。当然这些都仅仅是猜测,可能很不靠谱。

陈雄华    写道
淘宝一天就处理了1亿零580万,而12306一天处理的交易仅仅166万条 ,如果从并发性上来说,淘宝的并发量远比12306大,但天猫的商品信息,促销数据都可以做缓存,做CDN,而12306的“商品”是一个个座位,这些座位必须通过后端数据库即时查询出来,状态的一致性要求很高。 
从这点上看,12306的商品信息很难利用到缓存,因此12306查看“商品”的代价是比较大的,涉及到一系列的后端数据库操作,从这个角度讲,12306的复杂度是高于天猫的。

范凯    写道

这个我确实不知道,需要请阿里系的专家来解读。 
(小编:阿里专家正在路上,Coming Soon!敬请期待!)

陈雄华    写道
这是一个系统性的功能,简而言之就是:分布式和缓存。

范凯    写道

据我个人了解的八卦,去年春运12306宕机之后,曾经求教过阿里,当时阿里派出了一支技术团队去了解情况和提供建议。 实事求是的说,12306相比一年前还是有所进步的,不知道是不是背后有阿里系专家的贡献。

陈雄华    写道
参见第7条。

范凯    写道

我觉得12306面临的主要挑战就是两个方面: 

陈雄华    写道
淘宝的商品相对独立,而12306商品之间的关联性很大,由于CAP定律限制,如果其商品的一致性要求过高,必然对可用性和分区容错性造成影响。 
因此,业务设计上,如果找到一条降低一致性要求时,还能保证业务的正确性的业务分拆之路。举个例子,火车票查询时,不要显示多少张,而是显示“有”或“无”,或者显示>100张,50~100,小于50等,这样就可以减小状态的更新频率,充分使用缓存数据。

czwlucky(来自论坛回复) 写道
12306网站的技术问题或许有多种解决方案(虽然可能并不完美),但最难解决的是业务问题! 
一列火车总共有多少张票?恐怕这个就难回答,即使是铁道上的人也不见得能回答的十分清楚。 
火车跟公交有几分相似,都有固定站点,每个站点都可能有人上下。不同的是,公交车可以先上车后买票,火车只能先买票后上车。我想这才是问题的根本。公交上去了就上去了,上不去可以等下一趟。火车得先有票才能上车,可是卖票规则却成了难解之题。

范凯    写道
高性能并发系统其实分很多种类,是并发读,并发写,并发长连接,还是并发事务?不同类型的架构设计是不同的。具体到12306就是并发事务,在这个领域,我个人没有什么经验。

陈雄华    写道
1)  优化前端网页 

2)  群集分发和调度 
据说12306是采用集中式构架的,集中式构架很难应对高并发,也很难水平扩容,分布式不是仅仅将调度服务器,应用服务器,缓存服务器,数据库服务器分开就行,应该进行更细的服务级划分,对业务进行服务细分,做成一个个松散耦合的服务,然后把这些服务独立分布式部署。 
3)  采用分布式会话 
为了可以进行灵活的请求调度,不应采用weblogic、websphere这些应用服务器自身的session管理用户会话,而应该自己管理会话,如将会话保存在独立的集群memcached服务器中,这样每个应用服务就都无状态了,会话的请求可以随意分发给不同的服务器。这也是我的ROP开源项目没有使用HttpSession,而专门抽象出一个SessionManager接口的原因,开发者应该自己去实现这个接口实现分布式会话管理。 
4)  关于数据库设计优化 
数据库往往是系统瓶颈所在,首先应该对数据库进行分库设计,可采用两级水平切割,如首先切割成几个物理库,然后在物理库内部再采用表分割,一般是通过某个业务ID进行取模切割,降低单库及单表的并发性,提高TPS。 
合理采用读写分离技术,做到读写分离,可以一写多读,有效降低数据库的负载,数据的同步可以视情况采取应用层同步写,读取数据库日志更新或直接使用mysql读写分离技术等。 
此外,业务服务化、服务解耦化是关键。

runfriends(来自论坛回复) 写道
个人认为针对不同的系统要有不同的设计方案。 
虽然12306可以归类为电商领域,但是跟通常意义上的B2C还是有巨大的差异。所以单纯从12306上面讨论高性能并发系统架构并没有通用意义。 
不过,有一个思想应该贯彻。那就是所有访问力求分散到不同的服务器处理,不同类型的资源要坚持使用不同的集群服务。动静分离、读写分离,减少一次页面访问的请求数和数据库访问次数,保持小事务粒度,注意线程安全,避免大数据量的查询,建立索引(多表联合、union、非参数化sql、笛卡儿积计算、返回大数据集等数据库操作应该避免)。 
对于变化较小的查询操作可将查询工作交给专门的索引服务器完成。不过个人感觉像12306这样的业务,引入索引的意义不大也没有必要。 
12306的业务需求乍一看似乎都是同一类型的资源,但是我们可能根据车次、卧、软、硬、站、时段、线路等信息将车票这个12306要处理的惟一类型的资源分成若干子类,不同的子类请求由不同的集群处理。

范凯    写道
NoSQL的优势在于海量无模式数据存储和查询,12306的挑战在于并发事务处理,所以用NoSQL无助于解决12306面临的问题。

陈雄华    写道
纯用NoSQL个人认为现在还不成熟,毕竟NoSQL的状态一致性不好。一条可行的路子是MySQL+NoSQL,通过nosql缓解后端MySQL的压力。 
当然这涉及到很多业务流程的优化设计,降低数据一致性要求后才能合理使用NoSQL。

runfriends(来自论坛回复) 写道
事务的粒度应做到购买行为是原子性的,即保证两个人不会买到相同的票即可。每个票种的优先级是一样的,应不同的查询条件保证能尽快的返回。 
实际上每天出售的票种总和远达不到海量的程度。但是每年有几个时段并发量特别大。如果使用大量nosql数据库集群,票量一致性恐怕难以保证;如果使用单台nosql,恐怕吞吐量和实时响应也会像mysql一样难以做到。 
不论什么数据库,都难以完成这么少的数据量却要完成这么大并发量的情况。 
个人认为还是把不同票种分散在不同票池服务器中,完全由程序操作内存完成查询和购买更合适一些,虽然数据结构可能要复杂很多。 
最后根据每个票种的余票量要限制每个票种的查询和购买并发量。超过的就拒绝访问,以节省资源。早死早超生,而不是所有人都耗在买票这个事上。

范凯    写道
其实用WebLogic应用服务器,Oracle数据库,SSH框架和C3P0连接池都是OK的,但要解决12306面临的并发事务问题,需要系统在基础设施和架构上做很多专门的调整和开发的工作,  这些才是解决问题的关键,和用什么软件和框架关系不大。

陈雄华    写道
预算很大一部分都要来买weblogic、oracle的授权了,好钢用在了刀背上。完全可以用jboss代替weblogic,用mysql代替oracle,把这些省下的钱请技术专家,远比买这些东西好用。 
另外,这种高并发的互联网的应用不建议使用Hibernate,建议直接使用Spring JDBC,毕竟Hibernater操作数据库往往不够细粒度。另外还建议使用Spring MVC替代Struts,Spring MVC比Struts更高效性,页面尽量使用客户端的技术而不要使用服务端的技术实现,如使用客户端的requirejs+underscore客户端模块就比使用服务端的JSP或Freemarker要好,毕竟这样就让客户机来负责页面渲染了,且可以有效地使用CDN。

范凯    写道
12306从前端页面上来看用户体验就比较差,至少从页面设计和前端JS代码上来说就有巨大的改进空间了。后台架构上需要解决高并发事务处理,和分布式数据同步的实时性和一致性问题,在这两个问题上,我个人也没有太多相关实践经验,有一些个人的想法,但还是不误人子弟了,这些方面可以请阿里系的专家来解答。

陈雄华    写道

runfriends(来自论坛回复) 写道
铁道部应该对每节车厢、每个车次要卖出多少站票、软座、硬座、卧铺有一个规划。购买同一车次和票种的人不会造成太高的并发。因此关键在于查询和买票服务器集群的设计和实现。 
设计一个票池系统,按照车次、线路、区域划分票池,按照车次、站、软、硬、卧分类不同票种,将每个票种分配到票池集群的某台服务器上。买票时肯定已经确定了票种,通过一致性哈希准确定位指定票种所在的服务器。票池系统完全采用内存储存预售票票种、票量信息。 
查询、购买分开不同的集群,两个集群之间实现余票量同步。保证每个操作迅速返回,不必保证查询和购买实时同步,也不必保证查到的票在购买的时候一定能买到。

runfriends(来自论坛回复) 写道
第一:专业的事就应该找专家来做。不论招标也好,还是私下里寻找合作伙伴也好,都应该挑选有高并发、高吞吐量这方面的专家完成。而这样的人只存在于大型电商公司。铁道部花了那么多钱却没去找正确的人来做这件事。 
第二:关键在于目的是什么。目的是花钱,还是为了方便买票,还是其它目的? 
第三:关于抢票插件的问题。如果网站本身响应迅速,抢票插件也没什么市场了。关键在于要去考虑怎么改善用户体验,而不是要去禁抢票插件。上头意识从来都没有做正确的事。 
酷壳博主说,就为了一年那么几次,十几天的高访问量,花那么多钱开发一个购票网站,也就铁道部能做的出来了。 
个人觉的,更好的做法是。铁道部应该可以把购票api开放出来。让所有人都可以通过这些api开发购票网站。让这些网站之间形成竞争。 
这样访问压力分散到了不同公司的服务器,而铁道部就是做了一个平台。这样做的效果更好。就像现在很多类似携程这样的网站都可以在上面订飞机票一样。 
另外,通过云计算将根据一年中不同时段的压力弹性改变计算资源,也可以节省成本。
wangshu3000(来自论坛回复) 写道
问题瓶颈(Front to Backgroud): 
分析: 

http://blog.csdn.net/blogdevteam/article/details/8572108

更多相关文章
  • 前言 春节期间,无意中看到一篇文章,文章中讲到12306的业务复杂度远远比淘宝天猫这种电商网站要复杂.后来自己想想,也确实如此.所以,很想挑战一下12306这个系统的核心领域模型的设计.一般的电商网站,购买都是基于商品的概念,每个商品有一定量的库存,用户的购买行为是针对商品的.当用户发起购买行为时, ...
  • CSDN社区专家分享会:我的Android开发技巧从Google官方推出的Android培训课程.Android Developer Blog到众多Android开发者的技术实践与经验分享,不仅为新手提供了非常棒的入门教学,节省大量的时间与精力,更带来了丰富的工具与技巧.8月1日建军节下午,CSDN ...
  • 2013年4月的QCon北京会场上,两位在运维界打拼多年的技术男聚首专访间,就"运维人员的终极发展目标"这个话题展开了深入的讨论.他们是:邵海杨(个人页面),网名"海洋之心",系统架构师,业余撰稿人,十多年来一直致力于开源软件及前沿科技的研究和探索,目前在又拍 ...
  • 如果把12306外包给IBM或者阿里巴巴来做,能否比现在做得好?也行每个人里都有一个答案,我们这里不分对错,只谈谈个人看法.在平时,12306也就是个正常的电商网站.但一到黄金周,12306就是一个全站所有商品都秒杀,所有SKU(库存量单位,物流管理术语)都是动态库存的变态.媒体人喷12306,是他 ...
  • 在产品开发中,常常遇到产品性能问题,这些性能问题会很大程度上影响到产品的架构.但解决这些性能问题,切莫认为只是技术人员的事情,产品经理和产品总监也要参与其中,甚至是业务人员(销售.售前).下面以12306的售票问题为例,来做一个完整的说明.本文的目的,不是说技术性优化不必要,而是说作为开发人员不要闷 ...
  • SAP中国商业同略会IBM专家谈SAPHANA
    2012年7月27日,SAP中国商业同略会,51CTO记者邀请大会赞助商IBM的工程师分享了IBM在HANA方面的经验,IBM中国SAP技术架构总监李冬林认为,因为使用内存计算的特点,未来基于HANA平台的应用设计会将多个系统集成在一起,降低整个信息处理的复杂度,高效的系统使交易和分析处理可以同时并 ...
  • Power 7系统发布之后,不同搭配,各种型号的产品陆续开始供货.除了之前在 专访IBM Power总经理 纵览Power 7新特性一文中介绍的四款,本月将有包括刀片在内的多款产品在国内发布.有幸从IBM专家Rob McNelly的博客中看到不少新鲜内容,计划逐个转引过来,供关心Power7应用的朋 ...
  • 微信号 VMCloud (上图是根据业务60%.数据40%的比例,使用IOMeter测试出来的结果,比较精确)  ① 复制『微信号或ID』,在『添加朋友』中粘贴搜索号码关注.② 点击微信右上角的『+』,会出现『添加朋友』,进入『查找公众号』,输入 VMCloud ,即可找到.③ 红字ID部分长按均可 ...
一周排行
  • VMCloud云平台SCVMM配置六创建SQL服务模板准备
    继续上一篇完成SCVMM通过模板创建虚拟机后,本篇将继续讲述云平台中的第一个组件--SCV ...
  • puppet之service管理
    本文系统Centos6.0主机信息:master:master.lansgg.com 19 ...
  • Spark官方文档 - 中文翻译 Spark版本:1.6.0 1 概述(Overview) 2 引入Spark(Linking with Spark) 3 初始化Spark(Initializing Spark) 3 ...
  • 启动android模拟器,弹出了SDL_app:emulator.exe 的错误 说我指令引用的内存不能为可写的.造成这个错误的原因是你在模拟其上创建 sd卡文件,但是当模拟器启动时由于路径错误,找不到sdcard. ...
  • 巧用WebBrowser实现代码操作网页
    回顾一下上一个随笔,给出了两种方法自动化操作网页篡改HTML代码,加载到WebBrowse ...
  • 本实验在虚拟机vmware workstation 11上进行,虚拟网卡使用host-only模式,安装centos6.6_64位操作系统.主机master:node1.test.com ip:192.168.245 ...
  • 蜜罐的配置模式① 诱骗服务(deception service)诱骗服务是指在特定的IP服务端口帧听并像应用服务程序那样对各种网络请求进行应答的应用程序.DTK就是这样的一个服务性产品.DTK吸引攻击者的诡计就是可执 ...
  • Silverlight是微软提供的一种Web前端应用程序开发框架,是微软RIA的主要应用程序开发平台.Silverlight以浏览器的插件方式,提供丰富的多媒体展示功能以及更多交互性的Web前端解决方案.本文的重点在 ...
  •  项目实施():1.Web1上配置NFS服务,导出/www/htdocs以读写方式给Web2访问:(不能给其它主机以访问权限)   解说:web1的ip是:172.16.7.1 web2的ip是172.16.7.2  ...
  • 20145337Java程序设计第四周学习总结
    20145337<Java程序设计>第四周学习总结 教材学习内容总结 继承与多 ...