声明:ITeye精华文章的版权属于ITeye网站所有,严禁任何网站转载本文,否则必将追究法律责任!
由于春运,铁道部官方订票网站12306流量暴增,其Alexa排名一度进入前200,网友戏称,12306已经成为“全球最大、最牛的电商网站”。由于流量激增,12306系统频频瘫痪,一度出现登不上去、登上去抢不了票、抢到票需排队、排队后出票失败等局面。系统的用户体验、性能遭到用户大量的不满。
我们邀请了几位系统架构方面的专家,请他们从技术的角度为你剖析12306(我们会陆续增加其他几位专家的回复)。同时我们还从论坛活动(
畅聊12306,赢精美礼品)中选取了一些精彩回复。如果您对这些问题有独到的见解,欢迎在本文中评论或参与论坛讨论。
您是否在春节/国庆期间在12306上买过票?谈谈该系统的用户体验!
春运和国庆期间没有买过。但去年夏天在12306上面买过票,结果没有买到票,改买了飞机票。
我只用过一次,体验不深。感觉系统不太稳定,我访问的时候看到过Java出错抛出的错误堆栈信息。
有。界面很象是企业MIS,显得很粗糙,交互性,体验性都感觉很次。
我知道它很难用,所以我从来没用它买过票。去年国庆节查询个票,慢的要命。
从sql的拼写到页面优化,从程序架构到服务器架构都需要全面重构。居然不是参数化查询sql,而是查询参数拼到sql里的,完全是一群业余选手的习作。
应该采用js、css、图片、html都应该启用gzip压缩,所有css应减少到一个,js文件该合并的合并,能重用的重用,页面背景图应尽量合并成一个文件。尽量减少http请求数。
12306在去年国庆之前进行了改版,加入了排队系统,您认为加入排队系统的目的是什么?缓解了哪些问题?
对具体情况我不太了解。我猜测,实时购票是一个高并发的在线事务处理系统,需要通过排队系统来缓解事务并发造成的锁定吧。
排队是缓解资源并发的一次不错的策略,可以在后端资源不足时,将客户端请求暂存在池中,方便系统资源的调度。
刚开始的时候看到网上很多人说它有一个巨大的事务。后来又加入了排队系统。至于为什么个人猜测可能是为了降低数据库压力。
而实际上,用户并发量并没有变化,排队导致大量访问不能尽快返回,占用了大量系统资源。实际上这样做降低了系统吞吐量。数据库压力有没有降低先不说,系统吞吐量肯定会降低。
我认为增加这个功能的意义在于,当你不能立即买上票时,不用再不停的反复刷新提交了,相当于银行里发给你一个“号码”,等叫你时你过来买票就是了,不用站那儿傻等。一方面增强了用户体验感,另一方面也能节约反复请求带来的压力。
但我认为买票难根本原因不在于这个,12306网站的压力自然是大的,但这表面的背后却隐藏着更多的问题,为什么一票难求? 我们问自己一个问题:究竟一列火车有多少张票可卖? 你会发现没有答案! 如果真的没有答案,那即便你把12306刷到爆,也无济于事。
所以我认为,在系统设计上不是问题,像淘宝、天猫一样有大量的访问者,解决方案也不是就一个。 问题还是在于业务的设计上,只有把出票规则定合理了,系统才能更好的为大家服务,我们也不用去刷网站了,压力自然也会因此而小一些。
无论是从新闻上了解的,还是我亲身经历的,都证明从始点站开始买票会相对容易些,因为开始出票时,票数还是较多的(虽然也不是很多,大家都似懂非懂的),但从中间站点开始买票,票数少的可怜,甚至是0(网络延迟造成的)。这里面有一个二次售票的概念,怎么把这个二次售票的问题解决了才可能改善购票难问题。
二次售票我相信有它存在的理由。 但问题时它存在的理由真的注定它只能是现在这样的方式存在吗? 我也相信这个业务规则一定有改进的地方。
公交车,火车,长途汽车,在售票方式与运输距离,输送量上有很大差别,但运输本质没有差异。我们是不是能参考公交运输中的一些优点呢?比如是不是有可能增加同一线路的车次? 如果不能增加车次,是不是可以考虑沿途换乘方案?
12306春运购票,与淘宝、天猫在双11期间的促销有什么异同之处?
相同之处应该都是高并发的在线事务处理系统,我猜测主要不同之处在于12306背后的票务系统可能不是一个集中式的系统,而可能连接各个铁路局票务系统,数据同步的实时性和一致性可能更复杂一些。当然这些都仅仅是猜测,可能很不靠谱。
淘宝一天就处理了1亿零580万,而12306一天处理的交易仅仅166万条 ,如果从并发性上来说,淘宝的并发量远比12306大,但天猫的商品信息,促销数据都可以做缓存,做CDN,而12306的“商品”是一个个座位,这些座位必须通过后端数据库即时查询出来,状态的一致性要求很高。
从这点上看,12306的商品信息很难利用到缓存,因此12306查看“商品”的代价是比较大的,涉及到一系列的后端数据库操作,从这个角度讲,12306的复杂度是高于天猫的。
淘宝、天猫是如何应对这种超大规模并发的?如何hold住暴增的流量?
这是一个系统性的功能,简而言之就是:分布式和缓存。
您认为这些经验中哪些可以应用到12306?
据我个人了解的八卦,去年春运12306宕机之后,曾经求教过阿里,当时阿里派出了一支技术团队去了解情况和提供建议。 实事求是的说,12306相比一年前还是有所进步的,不知道是不是背后有阿里系专家的贡献。
参见第7条。
12306在系统、业务设计上,还存在哪些挑战?
我觉得12306面临的主要挑战就是两个方面:
- 一、实时高并发在线事务处理;
- 二、如何和各个铁路分局票务系统对接,保证数据同步的实时性和一致性。
淘宝的商品相对独立,而12306商品之间的关联性很大,由于CAP定律限制,如果其商品的一致性要求过高,必然对可用性和分区容错性造成影响。
因此,业务设计上,如果找到一条降低一致性要求时,还能保证业务的正确性的业务分拆之路。举个例子,火车票查询时,不要显示多少张,而是显示“有”或“无”,或者显示>100张,50~100,小于50等,这样就可以减小状态的更新频率,充分使用缓存数据。
12306网站的技术问题或许有多种解决方案(虽然可能并不完美),但最难解决的是业务问题!
一列火车总共有多少张票?恐怕这个就难回答,即使是铁道上的人也不见得能回答的十分清楚。
火车跟公交有几分相似,都有固定站点,每个站点都可能有人上下。不同的是,公交车可以先上车后买票,火车只能先买票后上车。我想这才是问题的根本。公交上去了就上去了,上不去可以等下一趟。火车得先有票才能上车,可是卖票规则却成了难解之题。
您认为高性能并发系统架构应该如何设计?关键是什么?
高性能并发系统其实分很多种类,是并发读,并发写,并发长连接,还是并发事务?不同类型的架构设计是不同的。具体到12306就是并发事务,在这个领域,我个人没有什么经验。
1) 优化前端网页
- 充分利用CDN,使JS、图片等静态资源的请求能够就近访问(顺便说一下,如果12306订票插件能从google提供的http://cdnjs.com中引用JS,而不去直接引用github的JS,就不会把github搞瘫了)。
- 将JS、CSS合并,最小化请求数。将JS和CSS压缩,最小化数据传输
- 启用gzip压缩网页。
2) 群集分发和调度
据说12306是采用集中式构架的,集中式构架很难应对高并发,也很难水平扩容,分布式不是仅仅将调度服务器,应用服务器,缓存服务器,数据库服务器分开就行,应该进行更细的服务级划分,对业务进行服务细分,做成一个个松散耦合的服务,然后把这些服务独立分布式部署。
3) 采用分布式会话
为了可以进行灵活的请求调度,不应采用weblogic、websphere这些应用服务器自身的session管理用户会话,而应该自己管理会话,如将会话保存在独立的集群memcached服务器中,这样每个应用服务就都无状态了,会话的请求可以随意分发给不同的服务器。这也是我的ROP开源项目没有使用HttpSession,而专门抽象出一个SessionManager接口的原因,开发者应该自己去实现这个接口实现分布式会话管理。
4) 关于数据库设计优化
数据库往往是系统瓶颈所在,首先应该对数据库进行分库设计,可采用两级水平切割,如首先切割成几个物理库,然后在物理库内部再采用表分割,一般是通过某个业务ID进行取模切割,降低单库及单表的并发性,提高TPS。
合理采用读写分离技术,做到读写分离,可以一写多读,有效降低数据库的负载,数据的同步可以视情况采取应用层同步写,读取数据库日志更新或直接使用mysql读写分离技术等。
此外,业务服务化、服务解耦化是关键。
个人认为针对不同的系统要有不同的设计方案。
虽然12306可以归类为电商领域,但是跟通常意义上的B2C还是有巨大的差异。所以单纯从12306上面讨论高性能并发系统架构并没有通用意义。
不过,有一个思想应该贯彻。那就是所有访问力求分散到不同的服务器处理,不同类型的资源要坚持使用不同的集群服务。动静分离、读写分离,减少一次页面访问的请求数和数据库访问次数,保持小事务粒度,注意线程安全,避免大数据量的查询,建立索引(多表联合、union、非参数化sql、笛卡儿积计算、返回大数据集等数据库操作应该避免)。
对于变化较小的查询操作可将查询工作交给专门的索引服务器完成。不过个人感觉像12306这样的业务,引入索引的意义不大也没有必要。
12306的业务需求乍一看似乎都是同一类型的资源,但是我们可能根据车次、卧、软、硬、站、时段、线路等信息将车票这个12306要处理的惟一类型的资源分成若干子类,不同的子类请求由不同的集群处理。
有人提议12306采用NoSQL存储,您认为是否可行?
NoSQL的优势在于海量无模式数据存储和查询,12306的挑战在于并发事务处理,所以用NoSQL无助于解决12306面临的问题。
纯用NoSQL个人认为现在还不成熟,毕竟NoSQL的状态一致性不好。一条可行的路子是MySQL+NoSQL,通过nosql缓解后端MySQL的压力。
当然这涉及到很多业务流程的优化设计,降低数据一致性要求后才能合理使用NoSQL。
事务的粒度应做到购买行为是原子性的,即保证两个人不会买到相同的票即可。每个票种的优先级是一样的,应不同的查询条件保证能尽快的返回。
实际上每天出售的票种总和远达不到海量的程度。但是每年有几个时段并发量特别大。如果使用大量nosql数据库集群,票量一致性恐怕难以保证;如果使用单台nosql,恐怕吞吐量和实时响应也会像mysql一样难以做到。
不论什么数据库,都难以完成这么少的数据量却要完成这么大并发量的情况。
个人认为还是把不同票种分散在不同票池服务器中,完全由程序操作内存完成查询和购买更合适一些,虽然数据结构可能要复杂很多。
最后根据每个票种的余票量要限制每个票种的查询和购买并发量。超过的就拒绝访问,以节省资源。早死早超生,而不是所有人都耗在买票这个事上。
12306 如果使用开源来实现,您有什么建议?
其实用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需要着重改善哪些方面?如果让您来设计,您会如何做?
12306从前端页面上来看用户体验就比较差,至少从页面设计和前端JS代码上来说就有巨大的改进空间了。后台架构上需要解决高并发事务处理,和分布式数据同步的实时性和一致性问题,在这两个问题上,我个人也没有太多相关实践经验,有一些个人的想法,但还是不误人子弟了,这些方面可以请阿里系的专家来解答。
- web前端要大笔优化,采用requirejs+jquery+backbone+underscore框架,web应用要进行部署优化js合并,js压缩;
- 所有业务SOA化,以便可以将业务分布式部署;
- 数据库分库,二级切分,实现读写分离,从业务流程调整上降低对数据一致性的要求;
- 充分使用nosql技术,通过流程优化和调整,使nosql承担大量的数据访问请求,使nosql成为保卫后端mysql的一道坚强的保障。
铁道部应该对每节车厢、每个车次要卖出多少站票、软座、硬座、卧铺有一个规划。购买同一车次和票种的人不会造成太高的并发。因此关键在于查询和买票服务器集群的设计和实现。
设计一个票池系统,按照车次、线路、区域划分票池,按照车次、站、软、硬、卧分类不同票种,将每个票种分配到票池集群的某台服务器上。买票时肯定已经确定了票种,通过一致性哈希准确定位指定票种所在的服务器。票池系统完全采用内存储存预售票票种、票量信息。
查询、购买分开不同的集群,两个集群之间实现余票量同步。保证每个操作迅速返回,不必保证查询和购买实时同步,也不必保证查到的票在购买的时候一定能买到。
庄表伟:与12306相关的一些思考
铁路购票的12306网站,我也在上面购买过火车票,虽然的确存在着各种各样的问题,但是最终确实成功的买到了票,而且也顺利的坐上了火车。也许因为不是在春运期间购买的缘故,说实话,我对它的印象没有那么糟糕。
当然,如果我们看看网络上的新闻,搜索微博里的各种人对12306的批评、责骂与嘲讽...是的,他们做得糟透了。
但是,在我看来,痛骂他们的技术如何垃圾,并没有追踪到问题的本质,本文试着继续深入的追究下去。
一、不要外包
分布式系统的第一原则是:不要分布式!而外包系统的第一原则是:不要外包!前一句,有很多高人说过,后面这一句,是我杜撰的。而我之所以会提到这个问题,是因为网络上有很多类似的观点,似乎是因为这次的外包开发没有找好,如果将这个活包给淘宝、支付包、京东、亚马逊之类的大型成熟电商来做,就万事大吉了。事实上,这些成熟电商之所以成熟,恰恰是经过了长期的改进完善之后的结果,而且,一定是他们自己的开发团队完成的。另一个近在眼前的例子,想想苏宁易购吧。直接一点说,如果这事外包给淘宝来做,就算淘宝有人有时间也愿意接这个活,也肯定干不好。
为什么外包通常搞不好呢?因为他们不是自己人,他们没有跟着一个企业同步成长的体会。因为他们希望获得整理明白后的一本“需求汇总”,他们害怕反复不断变动的需求。当然,我这个观点,可能存在着某种偏见,但是,越是变动复杂,极其核心,影响巨大的系统,我都强烈的不建议交给外包来完成。
二、循序渐进
一个非常庞大的电商网站,都不是一天建成的,淘宝不是一天建成的,亚马逊、京东也不是一天建成的。我们怎么能够希望12306在第一次推出的时候,就能够支撑春运购票这样变态的需求呢?
为了限制需求,其实可以有很多种办法:比如限制特定的班次(只卖高铁票、卧铺票、只卖从起点到终点的票等等)、比如网络购票加价,比如只在平时提供使用而不是在春运期间投入使用。总之,不需要一开始就服务所有的用户,选定一个较小的范围,先服务好,再循序渐进,逐步扩大服务的范围、提升服务的效率与质量,才是较为稳妥的办法。
三、排队系统
在12306网站推出之前,我们的购票体验同样糟糕,客观的说,只怕更糟。但是为什么反而没有什么人来骂呢?很多人在说,因为12306的用户体验做得不够好,但是我想要反其道而谈之。如果网站的用户体验能够像当初的实际购票一样差,只怕反而更加好一些。
回顾一下传统的购票流程吧:来到购票大厅,首先要选择一个窗口排队,运气不好的时候,自己选择的那一队恰恰是最慢的。经过几个小时甚至十几个小时的排队,我们来到了窗口前,遇到的是心烦意乱的售票员大妈,她们通常态度恶劣却动作迅速,到哪里?没有!卖完了!只有站票了,要不要?不要就换下一个!看清楚了吗?确认我就出票了。
窗口前的购票者,在身后巨大的目光压力之下,在面前不耐烦的语言压力之下,做着迅速的购买决定。这种购票体验,真的是太烂了。唯一的好处是:当我们拿到了那张纸片,就放下心来,肯定能回家了。
假设,我们一开始就把12306做成一个售票大厅的模式,总共就100个窗口,每个人都登录以后先排上10个小时的队,一旦排上了,轮到自己了,购票时间不会超过2分钟。那么,虽然是漫长的10小时的等待,却不需要时刻守在电脑前站着。这种体验,我想就足够了。
从12306的角度而言,完全可以将系统按照每个城市一个售票大厅的方式来部署,一开始假设只有100个窗口,人再多也是这么排着。等到系统稳定了,能力上去了,再慢慢的增加窗口的数量,缩短排队的时间。痛骂的人,将会少很多很多。原因很简单,不要一开始就给用户一个很高的期待值,然后再让他们失望,而是基于现状,小步快跑的做着改进。反而会有较好的效果。
这种做法,其实在网游行业是基本常识,随着用户数量的增加,新增一组一组的服务器,以容纳更多的玩家,而不是一开始就放开让所有的人进来玩。宁可不让他们进来,也不是让他们进来以后,在游戏场景里玩排队的游戏。
四、代售机制
火车票代售网点,其实在很多年前就已经出现了。我认为这个模式其实很不错,是一个分散客流提高效率的好办法。假设,我们不做12306的网站,而是开办成千上万,甚至上百万的火车票代售网店,情况会变成什么样子呢?假设,我们降低火车票代售点的准入门槛:交XX万押金,下载一个代售点客户端,自备电脑,自寻场地,自寻客源,自己去做生意。搞一个简单的审批流程,每年新增批准10万个个体户代售点。
这样的好处是:每个企业,每个公司,每个街道办事处,都可以自己申请成为一个代售网点,然后解决身边人购票的难题。在最大限度内,减少集中排队的压力。另一方面,由于审批流程可以控制代售点的数量,同时也就保证了系统的压力始终以可控的方式增长。
我在内心默默推理了一下,似乎是一个较为简单可行的办法。
五、抓大放小
说起用户体验糟糕,每个人都可以滔滔不绝的说很多话。我们常常会看到这样一种言论:铁道部的官员,他们用12306吗?如果他们也用,难道不会更加促使12306网站更快的改进吗?
其实,从技术人员的角度而言,怕的就是大老板亲自抓用户体验。当然,比这个更加糟糕的,则是每个领导,都对用户体验,说三道四。
对于12306的改进,我想不必过于关注细节,追踪一些统计数据的变化情况就好。比如:平均购票等待时间;退票率与废票率;列车上座率等等。至于如何提高这些数据,领导们千万不要事无巨细的参与讨论,大家各自努力就好。有更多的事情得靠领导们努力:比如切实提高运力……
六、架构演进
在网络上,我们常常能够看到很多给12306支招的方案,总之各种前卫,各种先进。但是,在我看来,越是复杂的系统,越是怕这种“革命”,哪怕过去的架构再不合理,也最好不要贸然引入过于激进的架构,在原有的架构下逐步演进,逐步扩展,逐步寻找小范围的、能够被改进的点来推进,才是较为合理的做法。
我能够看到的很多对于12306的批评,常常是一直站着说话不腰疼的姿态,说实话,并不可取。就目前来看,我们最乐观的估计是,12306能够顶住压力,逐渐改进、完善,在3~5年之后,渐渐淡出人们的视线,成为一个普通的,日常必须使用的,生活服务类网站。
其他
第一:专业的事就应该找专家来做。不论招标也好,还是私下里寻找合作伙伴也好,都应该挑选有高并发、高吞吐量这方面的专家完成。而这样的人只存在于大型电商公司。铁道部花了那么多钱却没去找正确的人来做这件事。
第二:关键在于目的是什么。目的是花钱,还是为了方便买票,还是其它目的?
第三:关于抢票插件的问题。如果网站本身响应迅速,抢票插件也没什么市场了。关键在于要去考虑怎么改善用户体验,而不是要去禁抢票插件。上头意识从来都没有做正确的事。
酷壳博主说,就为了一年那么几次,十几天的高访问量,花那么多钱开发一个购票网站,也就铁道部能做的出来了。
个人觉的,更好的做法是。铁道部应该可以把购票api开放出来。让所有人都可以通过这些api开发购票网站。让这些网站之间形成竞争。
这样访问压力分散到了不同公司的服务器,而铁道部就是做了一个平台。这样做的效果更好。就像现在很多类似携程这样的网站都可以在上面订飞机票一样。
另外,通过云计算将根据一年中不同时段的压力弹性改变计算资源,也可以节省成本。
问题瓶颈(Front to Backgroud):
- Web端,每天请求上亿,压力很大,包括html js css img等,需要占用大量带宽
- 身份证认证,可能会用到第三方的认证,或者铁道部协议,获取到身份证信息,这个查询量也很大
- 交易,银行性能应该不在瓶颈
- 订票记录,采用按照车次分表,应该是集中控制集群,分表 分区 索引,速度不会太慢
- 查询余票,每次交易成功,更新订票数据,更新量较大
分析:
- 网站的内容可以分布式部署,采用apache+xxx分发,后台多个镜像分担请求,进行冗余;图片、css、js、html、动态jsp、后台业务,分别部署;并且对web进行部分优化,压缩,合并,缓存等。
- 每次订票数据流量在2M,每天1200w/8h/60min/60s,每秒420个订票请求,840M/s的网络流量,根据分布6种文件140M/s,一般光纤网络就可以了;每种文件下面分布几个cluster,性能足以支持,每秒70个请求。并不大
- 身份证第三方只要支持每秒1k+的并发请求就足以支持订票了。很容易
- 如果本地验证身份证,根据省份、建立表,根据城市建立分区表,速度也会非常快,用身份证做主键,一条身份证信息0.2k,全国13亿=260G的数据量,easy,做个RAC就足以支持这种压力了
- 银行不考虑
- 车次,订票记录,余票记录,每天7kw的记录,14G/天,保存20天,才280G
- 订票业务按照省份分布,每个省份单独结算
- 整体采用SOA架构,都是服务,每个服务专注自己的业务,优化自己的服务
- 银行交易需要大量校对和核实业务,也许要一些投入,算成本;需要对仗,异常情况分析等,属于不是直接业务的处理,不能省略。
- 硬件IO,视情况而定优化,EMC盘阵,RAID;数据分布存储,根据数据量划分group。
- CPU,内存通过简单增加刀的CPU和内存来提高。
- 网络,根据地点,业务分布到不同的节点进行购票,每个节点的网络吞吐可以控制,不会太高
分享到:
您还没有登录,请您登录后再发表评论
78 楼 wjs0702cn 2013-02-17 14:04
77 楼 fxk2006 2013-02-17 13:53
76 楼 jerry 2013-02-17 09:57
75 楼 lizewu 2013-02-16 14:57
74 楼 loookto 2013-02-16 11:09
73 楼 frankiehuang 2013-02-15 12:31
所有人都预先1个月选几个志愿班次,订票付款;查询车次是只读的发布成静态HTML,订票是纯写入数据库的操作,无需锁定,可以缓存写。性能绝对没问题。至于付款,那是网银的事情,系统只需要被银行出发确认款已经到。
放票就用批处理方式,按订票顺序按志愿优先顺序,把已经确认付款的票放出去。
买票人随时可以登入查询自己的订票成功与否。
订票失败的退款就完事了。
72 楼 MrLee23 2013-02-13 23:09
71 楼 evanzzy 2013-02-13 19:38
1、铁道部只做车票批发商,不面向最终乘客,车票零售交给淘宝、京东、去哪儿等做;
2、铁道部每小时(或每刻钟、每分钟,具体值待讨论)向各零售商批发一次票源;零售商的批发配额依据历史业绩确定;各零售商之间也可以按照车次或铁路线路分配票源;
3、铁道部每小时(或每刻钟、每分钟,具体值待讨论)对零售商做一次汇总;
3、铁道部夜间和零售商做结算。
这样做农民工更惨,这些“零售商”的倒票行为就成了公开合法的行为。而且,铁道部的政绩也无处体现。因为有农名工这个庞大的、相对贫穷的群体存在,在做铁路售票的顶层设计时,是必须重点考虑的。如果和技术有了冲突,那显然是技术要让路的。
70 楼 xuby 2013-02-13 15:39
1、铁道部只做车票批发商,不面向最终乘客,车票零售交给淘宝、京东、去哪儿等做;
2、铁道部每小时(或每刻钟、每分钟,具体值待讨论)向各零售商批发一次票源;零售商的批发配额依据历史业绩确定;各零售商之间也可以按照车次或铁路线路分配票源;
3、铁道部每小时(或每刻钟、每分钟,具体值待讨论)对零售商做一次汇总;
3、铁道部夜间和零售商做结算。
69 楼 runfriends 2013-02-08 11:05
所以说的都是些P话
综合ERP OA CRM 银行系统门户网站和我了解过的电商应用,确实考虑较弱的事务能带来更好的性能。只要保证不会重复卖出同一张票和所有票都能卖出就足够了。你说的要强事务,是不是要保证我查到的票就一定要能买到?这样效率太差了
68 楼 aws 2013-02-08 10:38
所以说的都是些P话
67 楼 ansjsun 2013-02-08 00:42
66 楼 minimu 2013-02-07 22:39
其实这真不是瓶颈。
你就是用ruby python这样的动态语言实现都没问题。
还有不要想存储过程了,在软件工程实践里面用太多存储过程是大忌。应当尽量杜绝。不是说它提供什么功能我们一定用它。好多人好像觉的如果采用了某种技术、框架、数据库,如果不用它的什么特性就好像不如不用一样或没有用的必要了一样。这种惟框架论、惟工具论不应存在。
还有tuxedo或cics这种东西,我不知道有没有商业友好的开源实现。它好像不是标准,是商用中间件实现。商用的东西很贵的。光维护成本就很高的。它又不是惟一高效、稳定解决方案。
它跟秒杀、我们通常认识的B2C等电商有巨大的差异。跟电信、金融类业务更没关系。
http://12306ng.org/forum.php
给大家推荐一个网站,京东的一个副总裁创建的网站。上面关于12306的讨论更有实际意义。有兴趣的也可以参与里面的项目。
你不放看看他们什么时候能出一个稳定的β版,然后评估下这个β版所能达到的效果?
当然,京东啊、副总啊、里面各位牛人,那么到时候同步出个人月数据应该不难吧?
拭目以待。
希望不会太久太久。
65 楼 dzl84394 2013-02-07 22:17
1,nosql啥的,不要再讲了,mysql以前没有授权和服务都被企业排斥在外,你们居然要nosql?你=本来就是强关系型数据的一个系统,你们居然说不能用关系型数据库?
2,我觉得和淘宝没有可比性,淘宝不要求数据一致性,我听过他们一些讲座,他们不同的人看到的东西是不一样的,对时效性要求也不高
3,谁说12306是集中式的?我知道他们18个铁路局用的数据库同步。。。。
4,数据库的事情,我以前公司尝试过这样搞:给50G内存,这样无论多大的数据库,都可以吧命中率提高到99%以上,和内存数据库没有太大区别,剩下的就是IO的压力了,这个内存数据库也有这个问题
5,12306介于企业应用和互联网网站之间,我做过2者,前者数据复杂,后者页面好看,但数据简单,重点不一样,12306显然2真都没有做好
64 楼 evanzzy 2013-02-07 22:00
Tuxedo和cics确实很贵,但是大量的银行核心系统都在采用,中外银行都是这样。不是贵就不能用的,而是看是否能够达到目的。中国某大型国有银行,买一台大型机就接近1亿元人民币——因为改软件风险太大。德国某世界级银行,也是靠买昂贵的服务器来提升性能,其人员向我们抱怨美帝的机器好贵。12306不是简单的电商网站,其运行稳定可靠对人民群众的生产生活有直接的影响,营收平衡确实很重要,但是有政治目的在里面,那是可以付出一定代价的。
另外有人主张让阿里或IBM做这个东西,那简直是不靠谱儿,也是缺乏政治敏感性的想法。这些公司是有外资在里面的,如果了解了铁路售票情况,是可以推算出中国铁路的真实运力的,尤其是列车编组能力,哪里是编组的关键节点,而铁路运力是直接关系到军事投送能力的——这就不是钱的问题了。铁路之所以成为一个部委,是与其战略性地位直接相关的,各种问题确实存在,但真要大规模调动人员物资,非铁路不可!
63 楼 runfriends 2013-02-07 16:37
可以使用设计优秀的内存数据结构保证查询和买票效率。不一定要依赖数据库。
62 楼 runfriends 2013-02-07 15:56
12036 的性能的测试有没有做,个人很有疑问?
对待高并发,大数据的交互。12306是怎么处理的?
12306的前端缺少是业余的选手做的.业务逻辑怎么处理的?
部分的编码习惯,sql的运用,个人很有疑问?
显然没有做压力测试。
连查询参数都是拼到sql里的,你说高并发、大数据它能怎么处理?代码风格和规范显然也没有,或者有但规范本身就很糟。
前端优化也没有做,这个不用怀疑。
就是业务选手的习作。
据说今年改善了很多,不知是什么样子。自从第一次登录什么都没查到以后再也登录过。
61 楼 yeshanren 2013-02-07 15:49
12036 的性能的测试有没有做,个人很有疑问?
对待高并发,大数据的交互。12306是怎么处理的?
12306的前端缺少是业余的选手做的.业务逻辑怎么处理的?
部分的编码习惯,sql的运用,个人很有疑问?
60 楼 runfriends 2013-02-07 15:25
我完全赞同二位的说法
我前几年正好在做一个国外的售票网站平台,所以看到12306的问题,以及后来增加的排队系统,我都比较熟悉,正好我们网站的排队系统是我做的。
我来说几个有经验的问题吧:
1.这类网站不能用hibernate。这根本不是问题,只要你能了解hibernate,其实很简单,如果对他有怀疑,就跟踪一下它发出的sql就行了,一般情况下,用hibernate还是jdbc,差别只在一些java运算的消耗而已,而这个消耗都在app server上,不占用瓶颈的资源,即数据库。
2.减少http请求的技术,如合并css,js的,和CDN的应用。这些解决的问题都是属于占用app server资源的,通常都不要紧,不是说他们没用,但通常不是这类应用的瓶颈。
3.核心问题还是票务方面的逻辑。火车票是属于有号的座位,票务通常分为无号码的票和有号码的,后者指的是要对号入座的票。这种票的额外负荷,就是相邻问题。
比如买两张牌,默认的,都是要相邻的,最好是一排,挨着坐的,或者对面的。有相邻问题就有空位问题,如果只买一张票,那么前后左右都有人的空座应该先卖出去。这是应该由系统提供自动执行的逻辑,还是比较复杂的,如果要做成非常人性化、非常合理的话。
我估计12306还不会达到这种程度,根据他们一贯印象,以及当前的现状推断。现在的问题是人家买不着票,而不是给了座位两个相隔很远的票。
4. 我的方案
各位高手给出的很多方案都可以试试,但如果是我来解决这个问题的话,我一定会先找瓶颈在哪里,用各种日志来跟踪分析,其实大概的瓶颈还是比较容易找的。
第二就是要建立性能测试环境。我们用过LoaderRunner做过2万并发请求(不是2万在线用户而是2万个请求同时买一个场次的票)。
性能测试环境做好之后就可以尝试各种方案了,方法会有很多,一定会有办法提升的,我确信。
我想到的最简单一个可行的方法,就是数据碎片化,也有人提到过,就是把不同车次的票放在不同的DB服务器里做,就好像大家玩的网络游戏,登录前要先选择登录的服务器一样。
但是这不是一个优先采用的方法,毕竟会增加更多的DB,增加维护量,也稍微降低了灵活性和界面友好性。
总之多个方案挨个试试,对比优劣,得出一个最优方案。
想到这个我就很有兴趣,我最喜欢做的就是这种事情啦,哈哈。
可惜这不是我的事,留给铁老大完成吧
荒谬,怎么是大忌了,还有人说用SSH是大忌呢,用不好就不要乱说。存储过程也是用来做业务逻辑,Java后台的控制代码也是在做业务逻辑,你两边一起用当然会乱的一塌糊涂。但别人说使用存储过程就是把与数据库写入相关的业务逻辑全部拿到数据库中,Java后台自然相关的业务逻辑全部去掉。
考虑到数据库的横向扩展比应用程序要困难很多,因此在中型以上的项目中,都要慎用或者尽量不用存储过程,从而节省数据库对资源的消耗,尽量提高单台数据库服务器的吞吐能力。
只有一种情形是要考虑用存储过程的,那就是“针对某个功能,如果不用存储过程,就只能把海量的数据读到应用程序里再做进一步处理”。这种情况下,不仅很耗数据库的资源,同时还很耗带宽,跟存储过程相比,就只能两害相权取其轻了。
小型系统应该完全没有用存储过程的必要。所以抛开存储过程代码可维护性差这一点不论,单从需求上讲,适合用存储过程的场景还是比较有限的。
59 楼 runfriends 2013-02-07 15:21
当然你可能想永远都不可能换数据库,但是谁能保证。
将来数据库成了瓶颈,而对数据库的优化已经到顶了怎么办。对数据库依赖过多还会有各种其它的维护上的困难。
如果自己实现,将来对代码优化到顶了,替换一种语言的实现比替换数据库要容易很多。当然不管换什么代码都不小。
其实业务逻辑完全用代码实现,为集群增加机器更容易。将来做数据拆分也简单。
完全使用存储过程实现业务逻辑,将来做数据同步、数据拆分还有其它集群节点的维护工作,业务逻辑的维护、需求变更等工作要困难很多。
我们都是按照自己的项目经历在说,我们的经历都大相径庭,也很难达成共识。
仅从我经历的项目来说,存储过程一直是被严格限制的。甚至有些公司禁止使用。
至于禁止的理由可能有些朋友认为跟不用ssh而用jdbc和springmvc的理由差不多。
不过从一个程序员的角度的角度考虑完全不用存储过程是首选。
即使从招聘的角度考虑,找到一个java程序员来维护代码要比找一个熟悉存储过程的人来维护存储过程容易的多。
每种数据库的存储过程差异很大,不可能精通每种数据库的存储过程。而会java的人很多。将来会python ruby的人也会越来越多。
从技术选型的角度,肯定要考虑到这方面的因素,除了效率,还要考虑将来的运营、维护、需求变更、招聘难度,等各方面的因素。
不知这位朋友你是从哪些方面考虑的要完全采用存储过程实现业务逻辑的呢?
至于有人说用ssh是大忌。
如果我分析这么说的原因,也只能是瞎猜了。大概也就是效率那方面的东西。开发难度ssh,和spring mvc jdbc没什么区别。就是api熟不熟的问题。
找一群熟悉ssh不熟springmvc的人来用springmvc开发可能要费些事,但是熟悉了也一样。要完成这个api的转换花不了多少时间。
至于说ssh的效率,前面我已经说了很多。用好了它们的性能差异几乎可以忽略。
荒谬,怎么是大忌了,还有人说用SSH是大忌呢,用不好就不要乱说。存储过程也是用来做业务逻辑,Java后台的控制代码也是在做业务逻辑,你两边一起用当然会乱的一塌糊涂。但别人说使用存储过程就是把与数据库写入相关的业务逻辑全部拿到数据库中,Java后台自然相关的业务逻辑全部去掉。
58 楼 yzwcroco 2013-02-07 15:19
荒谬,怎么是大忌了,还有人说用SSH是大忌呢,用不好就不要乱说。存储过程也是用来做业务逻辑,Java后台的控制代码也是在做业务逻辑,你两边一起用当然会乱的一塌糊涂。但别人说使用存储过程就是把与数据库写入相关的业务逻辑全部拿到数据库中,Java后台自然相关的业务逻辑全部去掉。
考虑到数据库的横向扩展比应用程序要困难很多,因此在中型以上的项目中,都要慎用或者尽量不用存储过程,从而节省数据库对资源的消耗,尽量提高单台数据库服务器的吞吐能力。
只有一种情形是要考虑用存储过程的,那就是“针对某个功能,如果不用存储过程,就只能把海量的数据读到应用程序里再做进一步处理”。这种情况下,不仅很耗数据库的资源,同时还很耗带宽,跟存储过程相比,就只能两害相权取其轻了。
小型系统应该完全没有用存储过程的必要。所以抛开存储过程代码可维护性差这一点不论,单从需求上讲,适合用存储过程的场景还是比较有限的。
57 楼 LucasLee 2013-02-07 15:14
我前几年正好在做一个国外的售票网站平台,所以看到12306的问题,以及后来增加的排队系统,我都比较熟悉,正好我们网站的排队系统是我做的。
我来说几个有经验的问题吧:
1.这类网站不能用hibernate。这根本不是问题,只要你能了解hibernate,其实很简单,如果对他有怀疑,就跟踪一下它发出的sql就行了,一般情况下,用hibernate还是jdbc,差别只在一些java运算的消耗而已,而这个消耗都在app server上,不占用瓶颈的资源,即数据库。
2.减少http请求的技术,如合并css,js的,和CDN的应用。这些解决的问题都是属于占用app server资源的,通常都不要紧,不是说他们没用,但通常不是这类应用的瓶颈。
3.核心问题还是票务方面的逻辑。火车票是属于有号的座位,票务通常分为无号码的票和有号码的,后者指的是要对号入座的票。这种票的额外负荷,就是相邻问题。
比如买两张牌,默认的,都是要相邻的,最好是一排,挨着坐的,或者对面的。有相邻问题就有空位问题,如果只买一张票,那么前后左右都有人的空座应该先卖出去。这是应该由系统提供自动执行的逻辑,还是比较复杂的,如果要做成非常人性化、非常合理的话。
我估计12306还不会达到这种程度,根据他们一贯印象,以及当前的现状推断。现在的问题是人家买不着票,而不是给了座位两个相隔很远的票。
4. 我的方案
各位高手给出的很多方案都可以试试,但如果是我来解决这个问题的话,我一定会先找瓶颈在哪里,用各种日志来跟踪分析,其实大概的瓶颈还是比较容易找的。
第二就是要建立性能测试环境。我们用过LoaderRunner做过2万并发请求(不是2万在线用户而是2万个请求同时买一个场次的票)。
性能测试环境做好之后就可以尝试各种方案了,方法会有很多,一定会有办法提升的,我确信。
我想到的最简单一个可行的方法,就是数据碎片化,也有人提到过,就是把不同车次的票放在不同的DB服务器里做,就好像大家玩的网络游戏,登录前要先选择登录的服务器一样。
但是这不是一个优先采用的方法,毕竟会增加更多的DB,增加维护量,也稍微降低了灵活性和界面友好性。
总之多个方案挨个试试,对比优劣,得出一个最优方案。
想到这个我就很有兴趣,我最喜欢做的就是这种事情啦,哈哈。
可惜这不是我的事,留给铁老大完成吧
56 楼 runfriends 2013-02-07 15:03
我前面说的那些东西就是为了能做到这一点。当然只是个人看法。
或者改成先充值预约,按预约顺序放票。什么刷新抢票DDOS的问题都解决了。想抓票贩子看网银消费记录就行了,关键是抓不抓,抓找怎么办。技术不是关键,关键是实现办法和运力,现在的问题是买不到票,还不是压力一上来服务就崩。
看来我也掉进惟工具论的错误了。根据我经验判断,过多的存储过程会对后面的维护带来更大的困难。时间久了维护各个存储过程之间的依赖也是个麻烦的事情,要改一改都要有巨大的胆量。
还有我说的就是完全用存储过程实现业务逻辑这种情况,这样似乎效率更高,但随之而来的问题就是数据库压力、数据库占用的系统资源更多,当资源占用达到一定程度就会造成性能瓶颈。对于开源数据库来说这是个很严重的问题,要对数据库做很强的优化,对dba要求相当高。至于商用数据库,由于要花钱我根本没考虑过。当然铁道部有钱。但是我想应该采用性价比更高的实现。
荒谬,怎么是大忌了,还有人说用SSH是大忌呢,用不好就不要乱说。存储过程也是用来做业务逻辑,Java后台的控制代码也是在做业务逻辑,你两边一起用当然会乱的一塌糊涂。但别人说使用存储过程就是把与数据库写入相关的业务逻辑全部拿到数据库中,Java后台自然相关的业务逻辑全部去掉。
55 楼 guwei999 2013-02-07 14:43
用什么框架是无所谓的。
用java也是没问题的。
我也是敢这样讲的。
hibernate很多关联映射的特性,用的太多确实会影响性能的,如果你不用性能跟纯sql是不相上下的,当然代码太烂就另当别论了。
不论用什么,太复杂的sql是应当禁止的。
你说效率低是你不会用的。阿里都用java做实时数据分析的。
不要老围绕着事务说事,我就认为这个东西就不应该有复杂的事务概念。
也别拿银行业务类比,完全不是一个东西。银行要求事务安全,数据一致高于一切。
这个卖票的网站,没必要要求太强的事务性操作。只要保证所有票都能卖出去,两个人买不到相同的票就行。
总之我的观点就是票查的到买不到属正常现象,票订到了付钱的时候又没了也没关系。
用的人很快就能通过网站知道到底还能不能买到票就足够了。
买到票的高兴,买不到票的骂一句S.H.I.T或者妈.的,再去想别的办法。
别让那么多人都在一遍遍刷新页面。那者是痛苦。
或者改成先充值预约,按预约顺序放票。什么刷新抢票DDOS的问题都解决了。想抓票贩子看网银消费记录就行了,关键是抓不抓,抓找怎么办。技术不是关键,关键是实现办法和运力,现在的问题是买不到票,还不是压力一上来服务就崩。
54 楼 nick.s.ni 2013-02-07 14:40
还有不要想存储过程了,在软件工程实践里面用太多存储过程是大忌。应当尽量杜绝。不是说它提供什么功能我们一定用它。好多人好像觉的如果采用了某种技术、框架、数据库,如果不用它的什么特性就好像不如不用一样或没有用的必要了一样。这种惟框架论、惟工具论不应存在。
荒谬,怎么是大忌了,还有人说用SSH是大忌呢,用不好就不要乱说。存储过程也是用来做业务逻辑,Java后台的控制代码也是在做业务逻辑,你两边一起用当然会乱的一塌糊涂。但别人说使用存储过程就是把与数据库写入相关的业务逻辑全部拿到数据库中,Java后台自然相关的业务逻辑全部去掉。
53 楼 runfriends 2013-02-07 14:28
其实这真不是瓶颈。
你就是用ruby python这样的动态语言实现都没问题。
还有不要想存储过程了,在软件工程实践里面用太多存储过程是大忌。应当尽量杜绝。不是说它提供什么功能我们一定用它。好多人好像觉的如果采用了某种技术、框架、数据库,如果不用它的什么特性就好像不如不用一样或没有用的必要了一样。这种惟框架论、惟工具论不应存在。
还有tuxedo或cics这种东西,我不知道有没有商业友好的开源实现。它好像不是标准,是商用中间件实现。商用的东西很贵的。光维护成本就很高的。它又不是惟一高效、稳定解决方案。
它跟秒杀、我们通常认识的B2C等电商有巨大的差异。跟电信、金融类业务更没关系。
http://12306ng.org/forum.php
给大家推荐一个网站,京东的一个副总裁创建的网站。上面关于12306的讨论更有实际意义。有兴趣的也可以参与里面的项目。
52 楼 runfriends 2013-02-07 14:12
当网站的效率达到不管用不用抢票工具都一样的时候,抢票工具还有存在的必要吗?
运力确实不足,不过网站也是有存在意义和必要的,它们是两回事,不要放到一块说。
51 楼 runfriends 2013-02-07 13:53
用什么框架是无所谓的。
用java也是没问题的。
我也是敢这样讲的。
hibernate很多关联映射的特性,用的太多确实会影响性能的,如果你不用性能跟纯sql是不相上下的,当然代码太烂就另当别论了。
不论用什么,太复杂的sql是应当禁止的。
你说效率低是你不会用的。阿里都用java做实时数据分析的。
不要老围绕着事务说事,我就认为这个东西就不应该有复杂的事务概念。
也别拿银行业务类比,完全不是一个东西。银行要求事务安全,数据一致高于一切。
这个卖票的网站,没必要要求太强的事务性操作。只要保证所有票都能卖出去,两个人买不到相同的票就行。
总之我的观点就是票查的到买不到属正常现象,票订到了付钱的时候又没了也没关系。
用的人很快就能通过网站知道到底还能不能买到票就足够了。
买到票的高兴,买不到票的骂一句S.H.I.T或者妈.的,再去想别的办法。
别让那么多人都在一遍遍刷新页面。那者是痛苦。
50 楼 nick.s.ni 2013-02-07 13:34
再说两句框架的事儿,我说铁道部这种系统,绝对不能用Hibernate,我是有直接经验的,我敢这样讲,就是用Spring Jdbc模板,iBatis都是多余。我倒是赞成售票的核心系统连Java都不能用,应该用Tuxedo或CICS,用C语言,外围系统用Java解决,就像银行一样。
请问核心系统是指最里面的订票逻辑判断吗?用Tuxedo或CICS还好理解,如果使用Oracle 是否用PL/SQL做逻辑判断会更方便。
Java肯定是拿来做Web 页面的了,做数据库内资料的操作确实不方便。
还有HTTP 协议问题,纯HTML页面太容易被解析URL路径了,还是要加其他的前端
技术比较好。
49 楼 evanzzy 2013-02-07 13:11
像12306这种高并发事务且一致性要求很高的系统,和银行比较类似,就是慢,慢在不能用缓存上面了,慢在数据实时查询上面了。上线时间短,系统压力又大,而且是突然抽风模式的大。用几个亿做这个系统说实话真不过分。一台SuperDome的小型机就数百万人民币,各种磁盘阵列备份系统也都是上百万一台,网络带宽开销和人员费用都高。各大电商做的时间长了,而且资金投入总额也远远大于12306(看看上市电商的年报就知道了),这么比不太合适。
再说两句框架的事儿,我说铁道部这种系统,绝对不能用Hibernate,我是有直接经验的,我敢这样讲,就是用Spring Jdbc模板,iBatis都是多余。我倒是赞成售票的核心系统连Java都不能用,应该用Tuxedo或CICS,用C语言,外围系统用Java解决,就像银行一样。