几次印象深刻的网上事故
在华为的时候自己带过几年的团队,团队的规模从一开始10多个人,到后来40多个人,负责的产品也从一个到多个产品,我自己的性格特点只能做一个小主管,做不了大领导,因为在遇到事情的时候,我总希望自己能够冲在最前面,也就是当当班长之类吧,所以我自己处理过很多次的网上事故的处理,当时和我一起处理事故的同学有的换了部门,有的离职,但是当时一幕幕经历就像刚发生过,在这里列举2~3个吧。
华为对于网上事故非常的重视,基本上如果个人的话导致网上事故的话,一年基本就白干了,二年内很多调薪、股票这些基本和你无关了,所以任何时候只要出现网上问题大家的精神都是高度紧张,而像我这样一个人负责几个产品,每个产品在网上都有很多局点的小主管,手机24小时开机,经常怀疑手机响了自己没听见。
我来华为第1次三级事故大概是在2011年左右,有一天晚上大概10点左右,有一个海外M国打来的电话说P系统手机首页有时会打不开,这时M国正好是下午,正处在业务的高峰期。我让一线的维护同学先用三板斧的重启,发现刚重启的好的几分钟是好的,但是一会就不行了。我联系了此项目的开发&PM W同学,我和W同学约好了一起找一个网吧。为什么会去网吧呢?因为在那个时候办公网络通过一层一层跳板机访问国外的网络不仅不方便,而且非常的慢,反而外面的网吧访问这些地方速度更快。到了网吧以后,很快的就登到远程的服务器,发现这次遇到的问题和我们以前的问题都不一样,以往最多的就是CPU过高、内存耗尽或者数据库连接过多,机器一旦重启以后几分钟就像整个世界突然变慢一样,为什么会突然变慢?这时已经到了晚上12点左右,从报问题已经近2个小时了,我们2个人在烟雾缭绕的网吧里已经江郎才尽。我的手机因为一直开着免提电用完了,W同学的手机接着上,电话会议里面研发、一线行销、运维、机关领导、RL等,这时我最担心的事情还是发生了,一线报事故了,报完事故以后,我的手机刚充完电,我的领导的领导给我打了几个电话,要求务必尽快解决问题。网吧里的人越来越少,而我和W同学仍然毫无头绪,电话会议上找了网络、存储、操作系统的专家,但是因为别人不了解我们的业务,也因为不是他的产品,往往给几句建议就下了,没有别人可以帮你,只有你自己。
于是我和W同学又重新整理思路,分析每一个异常的点,终于在凌晨1点左右,发现一个日志打印的量超过正常,我们前面其实找到了磁盘IO Wait明显不正常,但是没有找到为什么不正常?总想着是不是业务量太大,磁盘IO到了瓶颈了,而没有想到有一个日志文件打印的量太大。于是我们在网上找了一些命令,发现大部分的IO等待都是写这个日志导致的,为什么这样日志的量这么大呢?原来是跟踪日志的开关被调成了debug级别,先调回到error级别再找原因,终于在近凌晨2点左右将血止住了。接下来我们又花了10个小时左右分析为什么会导致这个问题,第二天中午12点左右我们离开了网吧,W同学回去休息,而我要回公司开始接受挨批,因为在我的产品出事故了。原因的分析我们花了10个小时,是因为要搞清楚什么开关会被调成debug,我们查询了最近所有发布的版本都出厂的开关都是error,怎么也不可能,直到早上6点多,一个一线的运维同学告诉我,他昨天做了一个操作,而这个操作正是无意中打这个开关打开,而他打开的目的是想收集一个数据,这个数据收集是因为一个外包的同学告诉他这是最快的方式。至此整个事故产生的链路很清晰了:
一线运维的A同学接到用户的投诉说某号码无法访问 --> A同学想自己解决,于是找了开发此版本的合作方的S同学 --> S同学指导其打开跟踪日志根据号码查询 --> A同学在线上业务高峰期间打开了此开关且忘记关掉此开关 --> 业务高峰期间跟踪日志量太大,阻塞了写日志的线程,而写日志是同步操作 --> 所有http请求的线程阻塞在IO操作上 --> 所有线程都耗尽业务中断。
之后一个月的时间我的时间都在回溯这个事故,暂且不分析为运维同学人为的错误,至少2点我们是没有做好的。
1、防呆设计: 并不是说运维的同学自己呆,而是避免使用的人犯错误。我们自己把日志调级别的功能放在控制台上,跟踪日志一打开全打开。
2、可定位能力差: 运维同学本来想自己定位解决,但是没有人告诉他怎么定位,开发同学告诉他怎么看,但是开发同学并不知道他会在生产环境定位。当系统中某个功能失效的时候,除了开发人员以外,基本没有人能定位。
从华为来到阿里以后,发现如果再重新设计这块的话,又会有不同的思路。对于可定位能力,我们可以全息日志采集,将每个用户在整个系统的走向异步的抓取下来,再同步到专门的日志分析系统,在这个系统中可以根据用户号码、订单号进行过滤分析。其次是防呆设计,这个在实际中很难完全避免,但是还是可以做一些工作,比如将开关和配置分级别,一些开关定义为P1,一些不重要的开关定义为P3,重要的开关只有个别人才能打开等等。
第二起事故大概是在2012年,海外某国反馈登录系统时会非常的慢,同样是在深夜去了网吧,这次算是比较顺利,很快的发现是某个慢SQL拖慢了, 这个SQL类似于select count(0) from user,经过分析发现是由于Oracle判断这个表是不是大表,如果判断大表,有一堆逻辑,感兴趣的同学可以自行在网上搜索。巧的是这张表大概几百万的数据,正好在Oracle判断大表的条件的外点,如果不是大表,Oracle会全表扫描,这一全表扫描速度就下降很厉害,加上我们的业务访问量很大,表现出来就是新用户登录很慢。
当时想着先解决问题,如果按华为的流程我们肯定是违规的,但是在巨大的压力下,解决掉问题是首要的。我们分析发现这个功能其实是判断当前已经注册多少用户,但是实现的方案很傻,每次登录的时候都去select count(0)。想到快速解决的方法,就是把这个sql干掉,于是我们不远万里把这个jar拖到本地,把这个sql改掉,再让一线运维的同学上传上去,重启解决。这个路子很野,但是当你面临棘手问题时,能解决问题就是很办法。
后面还有很多,后续我会慢慢的说来...