系统崩溃,大圣归来
走在程序员的路上,久了总会碰到一些系统崩溃的事件。
在 2011 年 8 月份某个阴雨连绵的周一,北弗吉尼亚一个 1000 万瓦特的变压器发生爆炸,在整个电网中带来了庞大的突增瞬间电压,对亚马逊位于弗吉尼亚州阿什伯恩(Ashburn)的一个数据中心造成了重创,导致这个数据中心的主电源关闭。亚马逊的杰出工程师詹姆斯·汉密尔顿(James Hamilton)当时正巧开车驶入该数据中心停车场,对于阿什伯恩数据中心来说,汉密尔顿在那个时刻到来是一个意外的惊喜,正当他们遭遇重创时有「大圣」经过帮助处理这些棘手的问题,真是再好不过了。
初入猿道的第一次系统崩溃当我还是一个稚嫩的小猿时,刚拿到公司 offer,还没毕业就去将来公司实习没多久就碰到了一次系统崩溃事件。一个稳定运行了十多年的老程序,从某一天开始就突然崩溃。一开始团队里经验老到的高工认为也许只是一个意外事件,先把程序重启起来让业务恢复。第一次崩溃重启后程序又恢复了平稳运行,安稳的一天就这么过去了。可从第二天开始,程序又莫名的崩溃了,然后我们又重启了,但没多久后再次崩溃了。《星际穿越》这部电影给大众普及的一个定律:墨菲定律,适时的生效了。
如果你担心某种情况发生,那么它就有可能发生。会出错的事,总会出错。
之后每一天这个程序崩溃的次数变得越来越频繁,团队里的人一时都反应不过来发生了什么。一个稳定运行了十多年的系统,怎么突然就这样了。而开发这个系统的程序员和公司早已不知所踪,我们公司只不过接手维护而已。费了老大劲终于从归档源码光盘中找回了当初这个系统的源代码,项目经理安排了几个高工展开了攻关,而我这个初来乍到实习生就负责盯着程序运行,发现进程意外退出就立刻重启。
两天后,高工们找到了原因并顺利修复了问题。触发的根源在于系统的交易量突然产生剧烈变化,而且这种变化是逐日大幅递增,第一次瞬时交易量突破临界点时,程序处理不当导致指针异常直接退出。而这个程序正是处理银行和证券公司之间资金进出的,当时正是 2006 年,中国 A 股悄然引来一场有史以来最大的牛市。
经历了这次事件,初入猿道的我开始明白系统崩溃这样的事件在我之后的道路上还将反复出现。
接踵而至的第二次系统崩溃如我所料,第二次系统崩溃很快接踵而至。在我正式毕业入职公司后不到三个月,进入了当初实习的项目组。在组里我成了唯一一名 Java 程序员,因为当时银行的大部分核心交易类系统都是 C 写的,所以整个项目组有经验的高工基本是 C 程序员。后来 Java 企业应用兴起,一些管理类应用,银行也开始用 Java 来开发,所以一些老的 Java Web 维护项目也开始落在我们团队来维护,实际也就是我一人来维护了。
这次崩溃也来的突然,早上银行结售汇的业务负责人打来电话说系统出错了,总行今日下发的外汇牌价导入出错。外汇牌价导入不了,意味着整个今天的结售汇业务无法开展,分行相应窗口全部都得停业。项目经理立刻让我查看怎么回事,我尝试将数据文件导入,观察后台日志,果然报错。但这也是我刚接手的一个维护系统,代码还没来得及看两行呢,后端都是 Java 写的,所以团队里一堆 C 的高工此时也帮不上太多忙。但看那错误来自一个解析 Excel 的第三方开源库的错误堆栈,一时看不出个所以然,只是奇怪为啥昨天都可以,今天就不行了。
初步判断可能是数据文件格式变化了,拿出总行下发的过去几天的牌价文件人工比对。但肉眼逐行检查怎么也看不出区别,时间一分一秒的过去,一小时后故障升级到银行分行副行长那里,副行长也坐不住跑到信息部和信息部科长一起来过问到底发生了什么。我们的项目经理陪着说正在排查,估计副行长一看就我一个毛头小伙在处理这个问题,很不满的对项目经理说为啥不多安排几个资深工程师来看,项目经理石破天惊的来一句,说对这个问题我就是最资深的了。我回头瞥了一眼,银行信息部科长不置可否的对着项目经理讪笑一下,他是最了解我们这个外包维护团队成员构成的了。
副行长一行人站我背后看了有半小时,可能觉着短期内也解决不了,立刻电话通知业务部门公告系统维护升级,下周一才可办理结售汇业务,幸好当时是周五为我们争取了周末两天时间。当然最后我也查出了问题并顺利修复,确实是数据文件格式发生了变化,这种变化从界面上看不出,解析程序却能感知到并很不友好的直接抛错了。
第一次系统崩溃,我站在边缘处。这次崩溃,我则站在了爆炸的中心。经历这次崩溃事件,我开始领悟到那些「大圣」不仅有火眼金睛能发现 bug,还能看清能处理状况的人,身心皆如玄铁方能在爆炸的中心站的住。我只是幸运的站在「大圣」身边方能在爆炸中心安然无恙。
求助你的人让你成为了「大圣」一年后,我离开了第一家公司,从银行转到了电信行业,适逢电信收购联通 CDMA 准备大力发展自己的移动业务时。公司定义了一套以配置适配不同省电信公司特定情况的产品,开发了快一年后,在当年底准备拿人口最少的电信省份海南做试点。我作为产品的主力开发人员自然被派到海南省支持现场实施,几个月后,处理了各种现场的意外情况后系统顺利上线,我也疲惫的回到广州。
在广州一个周末的晚上,我正在电影院看电影,海南现场维护的一个同事的电话响起,我犹豫着要不要接,在海南几个月几乎没有周末好不容易回了广州休整下又接到电话,正在犹豫中,电话响了几声后停了,我想如果紧急的话会再打的,但电影期间没再打过来。回到住处也没有电话再响起,我想可能也不是什么大问题已经处理好了就睡去了。半夜三点电话终于又再次响起,还是来自海南现场的同事,我挣扎起来接听了电话才知道出了大问题了,墨菲定律又生效了。
海南现场的同事先向我抱歉,他们本不想在我刚离开又在周末晚打电话过来,但确实他们出了状况已经搞不定了。我冲了把冷水脸清醒下,当时远程连不上海南局方的内网,只好通过同事 QQ 远程协助。因为适逢月底,一批计费结算的一大批量单突然下发,系统就陷入了崩溃边缘,磁阵 IO 跑满,而积压的工单按现场同事估算按这速度跑一天也跑不完,那到了白天开业新来的工单怎么办,所以没办法只好电话求助了。就这样从 3 点忙乎到早上 8 点,改了好几版程序优化 SQL,合并数据压缩等等,才终于把 IO 降下来,并顺利跑完昨天晚上的批量单。