12306已经成为每年春节绕不开的热点。在猴年的春运之际,InfoQ再次重拾这个话题,与各位一起探索这个影响亿万人的公共服务。正如小道君 所说的 那样,今年朋友圈里、微博上抱怨12306的少了。不得不说,这是一个很大的进步,唯有进步值得颂扬。希望明年我们不必再跟踪这个热点。
相信无数人已经见识过今年 12306 各种神奇的验证码了,吐槽归吐槽,我们来看看验证码到底是怎么回事?验证码的学名叫做CAPTCHA,即“图灵测试”(看过电影《 机械姬 》的同学因该对此并不陌生)。验证码通常是由计算机生成一个对人类而言很容易而对电脑而言非常困难的问题,能回答者被判定为人,但验证码测试其实不是标准的图灵测试。验证码的目的是阻止人类恶意利用计算机做受限的事情。早期的验证码大多用扭曲的文字来实现,用以避开OCR的机器自动识别。后来,验证码的复杂有时让真正的人类也难以识别。毫无疑问,12306对验证码的使用已发挥到了极致。
图像识别方法可以分为两大类,模型的方法和搜索的方法。模型的方法是在业界研究和使用最多的方法,基于搜索的方法直到大数据时代才出现。2012年前后,深度卷积神经网络在图像识别领域开始应用,此后,深度学习的方法击败了所有传统的方法,使得图像识别的准确率向前迈了很大一步。最新的 研究结果 使得识别率达到了96.3%。阿里巴巴研究员/资深总监华先胜先生表示,只要验证码系统不断快速地增加和迭代系统的数据,验证码的破解基本上是不可能的任务。
对于广大购票者来说,刷票软件并不陌生。浏览器厂商、黄牛党的刷票技能与12306道高一尺魔高一丈的对决,一度成为媒体争相报道的对象。我联系了著名刷票软件开发者 木鱼 并与之谈及了相关的话题,他源于个人使用而开发的刷票插件,曾一度导致GitHub遭受了DDoS攻击。
随后木鱼回忆了代码托管的几个阶段。
木鱼强调: 验证码识别绝对不是技术进步,而是技术的滥用 。因为购票需要秩序,你可以在守秩序的范围内为用户出谋划策,教他购票为他免去繁琐无用的环节,但你不能公然无视购票秩序越过12306设置的种种规则。验证码识别就是其中一个典型的技术滥用,可以说是对12306信息安全的一种攻击。如此下三滥,估计也只有国内的这些公司加不明真相的群众才能做得出来了。而木鱼在开发刷票软件过程中主要经历了如下几个阶段:
以上这些功能可以说订票助手都是首推并做得最好的。后来其中的一些功能也为其它的浏览器厂商所借鉴,但并不是他们的重点。很多的浏览器厂商(如数字、某狗、黄易等等)把精力放在了全自动上面(如验证码识别)。
对于国内各厂商的抢票版产品,木鱼评价如下:
总的来说,和12306对接的接口没那么复杂也并不是什么机密,所以在这之后的各大独立APP、软件等,其实可以说是大一统的场景,并没有基于谁的版本。木鱼认为在他之后,其实 并没有让我感觉眼前一亮的新功能设计 ,可以说超越其设计的功能的产品(无论是独立软件还是APP还是独立购票页面)并没有出现。
接着,我跟木鱼谈了一些前端技术的现状,木鱼感慨道:
不可避免地,我跟木鱼再次提及了抢票软件与公平的话题。木鱼的主要观点如下:
所以说,是不是会造成人为不公平,要看软件具体怎么做。
先前有文章报道了12306采用Pivotal GemFire分布式内存计算平台进行技术改造的过程,重点阐述了12306如何解决网络阻塞和集群性能水平扩展的问题。
笔者针对12306业务的特点,与京东云首席架构师杨海明作了一番简单的交流,主要内容如下:
12306购票业务与电商秒杀系统有诸多相似的地方。通常的秒杀系统包含 数据展示 及 数据处理 两个层面的能力:数据展示层面一般是通过CDN在全国范围内部署,实现各地访问的加速,因此访问层面的压力不大,核心瓶颈实际上在后台请求响应方面。后端必须同时能够支持高并发请求,并返回用户请求结果足够快。实际瓶颈不在CPU的处理能力,而在于I/O的吞吐速度以及数据一致性方面。在通常的电商秒杀系统里为了实现尽可能快一点,后端存储使用内存级别的操作,然后在慢速磁盘及高速内存中增加闪存卡,在磁盘阵列中增加SSD。虽然进行了磁盘层面的增强,但各地秒杀访问依然会带来数据一致性的问题,为了让全国各地的用户有平等的权利秒杀商品(比如新疆的客户与北京的客户)就需要部署多数据中心,同时实现多中心交易。
分布式内存计算平台(Pivotal GemFire)对于秒杀及12306之类的业务是一个正确的选择,但不是唯一的选择。在市面上还有其它各种分布式内存计算平台,在这里就不一一赘述了。但内存计算平台对于提升秒杀系统的处理能力毋庸置疑。此类业务的基本特性在于商品数目有限制,但在短时间内消耗光,查多买少;设计系统时,需要考虑读多写少的特性,尽量将压力往前端移,降低对数据层面的冲击。12306及秒杀业务的一个重要特点就是业务总量固定,比如12306对于一段时间的火车票是一个确定的数据量大小,秒杀业务在一个特定时间,商品的库存及商品的品类也是一个固定的数据量。因此,对于内存数据库层面,并不需要非常大的容量;相反,用户的请求如何合理的分散到各个负载服务器上,并汇总到这个数据后端,是秒杀平台设计优化的重点。
原则上,需要对12306的业务及数据格式充分了解,才能把握其瓶颈及拆分点。12306涉及的是国家的铁路命脉,可以通过铁路的形态进行拆分,比如高铁、动车、快车及普通车;也可以通过地域进行拆分,比如北京中心、上海中心、广州中心、西安中心;再或者根据以往购票查询热度进行划分。原则是将数据分到多个地方,降低中心的压力。
虽然外界报道12306业务是x86取代小机,但京东云首席架构师杨海明认为小机不会完全被x86架构取代。在所有12306的报道中,所解决的是查询的问题,而不是改变数据库的问题,小机+Oracle或者小机+db2的传统结构在确保数据一致性方面依然有绝对的优势。我们只是看到12306的查询库使用了分布式内存计算平台。也就是说,假设一个x86服务器出现问题,并不会造成铁路秩序的混乱;相反,增加x86的前端,非常适应之前描述的将压力往前端迁移的原则,将用户的访问压力用更廉价的x86来扛住,而把数据一致性和可靠性的任务交给更稳定更可靠的系统平台。在x86及小机的架构选择中,京东云首席架构师杨海明认为性能的瓶颈并不是绝对的问题。小机在RISC架构上的优势,在内存访问上的优势,及软硬一体优化的优势依然明显;相反,x86的廉价、生态的丰富、越来越强的处理能力及易用性方面,也越来越吸引大量的用户。在现在对于系统的选择、成本的控制,以及出现问题的责任影响,成为决策者考虑的因素。举个例子,如果12306的后台票务核心系统在春节期间出现2小时无法购票,那造成的将不仅仅是经济损失,甚至可能引起各种不安定因素;相反,如果某电商的秒杀系统无法完成交易,那损失是可以控制的。
CDN缓存解决的是用户访问端的问题,12306及秒杀场景下这些用户访问所带来的网络带宽是因为秒杀活动新增的,超过网站平时使用的带宽,这些带宽必须和运营商临时购买。为了减轻网站服务器的压力,更好地利用CDN、反向代理等性能优化手段,需要将秒杀商品页面以静态页面的形式缓存在CDN上。秒杀开始,用户刷新页面时,用户请求不会到达数据服务器,而是通过缓存直接提供给终端用户。用户体验的好坏,就是看CDN内容更新的效果。
至此,我们从前到后、从用户到开发迅速地遍历了12306的全貌。我们也有理由相信,随着时代的不断发展,这一关系国计民生、牵涉亿万人的公共服务会越来越好。随着春节假期结束,2016年的征程依然开始。愿InfoQ的读者在猴年里一切顺利。
InfoQ上还有几篇关于12306的内容,感兴趣的读者可以延伸阅读如下:
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群 (已满),InfoQ读者交流群(#2) )。