12306 的问题

来源:互联网 发布:ajax代码实例 java 编辑:程序博客网 时间:2024/05/18 16:56

关于12306的性能问题,是个技术人员都免不了吐几口吐沫星子。我也是,而且好好体验了一把。电话点票一个半小时,无果。电脑点票共三次,共计6小时左右,成功订票7张;外加失败订单2次,支付超时;登录成功若干次。

12306的用户体验

从用户的角度来看,12306订票有四关

  1. 登陆。用户需要反复输入用户名,密码,验证码。使用FireFox插件,只需输入验证码。验证码有时不清晰,需要刷新更换。用户点击登陆后,有时系统立马弹出对话框:访问人数太多,请稍后再试。有时则等待若干秒,页面被刷新,显示页面消息系统繁忙。
  2. 查询,主要是余票查询。
    • 用户需要输入起点站,终点站和日期时间。系统会返回两个城市之间所有的车次以及票务信息。比如上海有上海南,上海,上海虹桥三个站点,武汉有武昌,汉口,武汉三个站点,任意输入那个,查询结果会返回上海和武汉之间的所有车次。
    • 另外可以直接按车次查询。12306做了一个auto complete, 前端输入框会动态显示候选车次。autocomplete 响应速度相对算快。我试了几次按车次查询就没有使用了。一是响应速度和站站查询基本一致,二是单个车次命中(有余票)的机会相对很小。
    • 12306在前端脚本做了查询控制,每5s(?)可查询一次。
  3. 下单。如果车次有余票,则可点击预订下单。
    • 系统需要加载用户常用联系人的信息
    • 系统会显示一等座/二等座的价格,是否有票
    • 用户页面选择常用联系人和座位,填好票单,输入验证码,提交。
    • 页面弹出对话框确认用户的订单,确认,提交订单。
    • 系统一般显示当前提交订单人数太多,请稍后再试,用户只需要重新输入验证码,即可再次提交。
    • 尝试几次后,有可能下单成功;也有可能直接要重新退到第2步,重新查询;更多情况,是退到第1步,重新登陆。
  4. 支付。走到这一步,用户基本处在狂喜状态,以为票已到手。支付还不是秒秒钟的事情。
    • 用户点击支付后,如果顺利,则新开一窗口,跳转到一支付方式选择页面。
    • 选定支付方式(如招行),如果再次顺利,则跳转到银行页面。
    • 在银行页面支付成功后,如果再次再次顺利,则跳转到系统交易页面,生成一个流水号。
    • 上述三步,任意一步失败。用户退到第1步,重新登陆。订单从点击开始,进入45min倒计时阶段。
    • 如果成功,也是退到第1步,重新登陆。

从我的个人体验看,最难的两关是登陆和支付,这也是用户体验最糟糕的两步。登陆是最难闯的一关,验证码验证码验证码。。。,每次尝试等待若干时间,然后总是一个系统繁忙。这是令人着急和上火的一步。支付则是悲催的一步,订单到手,接着在45min内超时自动取消。

12306的瓶颈




上面是一个12306网站结构的预想图。除了网友用户,另外还有几万个订票窗口(北京在2009年有1254个)。似乎没有人说订票窗口查询或者提交变慢了。网友每天订票200w张,窗口出票300w张,平均是24张/s和35张/s,假设波峰时成功出票为240张/s和350张/s。共计590张/s。其中前者需要银行交互网络支付,后者则是出票即可。按照这种频率

  • 票务查询和修改,数据库端不是瓶颈
  • 网友用户基本上(登陆/支付)拥堵在前端号称只有两台的JBoss服务器上。
    • 没有足够的带宽/IO
    • JBoss 应用支持的并发数. 默认thread-pool大小是100
    • JBoss nio 说最大连接数可到8192

12306的优化目标

一个显而易见的问题是:12306无论做的多么nb,它是无法让每个人买到票的。其优化目标就是在保证公平的情况,更好的用户体验。理想状况

  1. 登陆一次提交即可,也无需等待,无需排队。
  2. 查询无需等待。
  3. 短时间出票完毕,先到先得。用户无需不断的刷票。
  4. 不管是买到票和没有买到票的用户,操作时间都不长,基本上就等同于taobao和团购上的限量秒杀。

量化目标就是:

  1. 12306要支持 n 个 用户同时在线
  2. 12306需要支持 m/s 的查询
  3. 12306需要支持 p/s 的订单提交
  4. 12306需要支持 q/s 的支付

第一参数,同时多少人在线。需要买火车票的有学生,白领和农民工兄弟三个群体,网络订票的主力是白领和学生。2010毕业大学生为630w,我们估计在校大学生为2400w左右, 40%的人需要买票(城市学生/非城市学生比例),再80%的人选择网络购票(2/8原则),学生在线买票为768w,白领购票假定为10倍(10年后白领们升级了,或买房,或买车,或机票)为7680w,一共为8448w。然后就是将这些人平均分摊在除夕的前10天,每天有844w的人会访问12306。


上面推算靠谱吗?根据alexa

日均 IP 访问量[一周平均]日均 PV 浏览量[一周平均]≈ 5,412,000≈ 21,972,720


姑且按照800w来计算,划分在4个时段,每个时段200w/2小时,假设每个用户会查询60次,平均每秒响应1.6w次查询。

订单的提交和支付则少许多,如果1/3之一买到票,则为90/s,高峰时段乘以5,则是450/s。所以12306的优化目标是:

  1. 12306要支持 200w 个 用户同时在线
  2. 12306需要支持 1.6w/s 的查询
  3. 12306需要支持 450/s 的订单提交
  4. 12306需要支持 450/s 的支付

如何优化

云风的排队解决公平问题,用户从不断的登陆尝试变成一个队列等待,可以改善用户体验。

靠谱的网站主要从应用切分的角度来分流用户请求,注册登录,查询和订票分发到不同的服务器。

个人浅见则主要从数据端使用redis进行缓存优化。


总结下来,可以做的优化有:

1) 应用层的服务器切分,全局的个人session存放是个问题。存放到数据库或者集中(分布式)缓存中?

  • 按功能切分。登录,查询,订票各自分离
  • 按用户IP/区域/email字母划分

2) 数据层的切分和缓存

  • 按起始站分库或者分表
  • 车次信息单机缓存
  • 余票信息集中分布式缓存

其他方案有

1) 开放API来查询预订火车票,由taobao等公司来接入。省去应用服务的优化环节。

2) 租用云计算服务,how ?

后记

12306购票揭秘:每分钟限1万人, 是否可以解释为:

  1. 12306 同时在线人数限制在1万
  2. 12306 每秒订单数为 167/s

难怪网络购票这么拥堵.






原创粉丝点击