报告老板,摊上大事了!

报告老板,摊上大事了,我们负责的联通某系统(系统A)出现客服大量断线的情况,导致用户投诉量激增,客服业务量受到严重影响!!——2014-01-16日,联通大厦。

山雨欲来风满楼

临近新年,手头上的工作也处于结尾状态,每天来到公司做些小的需求,修改些小的bug。该过年了,为了安安心心过大年,我们要确保系统的稳定性,所以年前是不会有大的升级改造的,这是我们打的如意算盘。昨天晚上升级系统B,升级过程不太顺利。主要是升级时备份文件,上传补丁文件都是手工操作,这样容易拷贝错文件或遗漏补丁文件,效率低还容易出错。最终折腾到夜里2点多总算搞定,害的小伙伴们和我一起熬夜,实在过意不去。

早上,拖着疲倦的身体来到客户现场,无精打采的坐着(最近总是感觉睡眠不足),看着QQ群的图标一闪一闪亮晶晶,却没有打开它的念头,真想大睡一觉啊!

中午时分,客户群里反应各省客服出现同时掉线的情况,严重影响客服业务量,让我们排查原因。这种情况以前也出现过,不过是个别客服人员。掉线的情况一般是网络状况不好,造成消息发送丢包,由于个别情况影响不大,我们一般也不会认真处理,只是应付过去罢了。今天情况确实很特殊,我们本地测试也出现集体掉线情况。于是技术经理登陆VPN查看了服务器情况,发现FS(负责消息处理,相当于Server)和Cassandra内存已满,于是和客户负责人联系下,我们这边重启了服务器。本以为这样万事大吉,谁知下午3点左右掉线问题又出现了。此时,查看服务器内存,日志文件,一切正常。这段时间系统A也没有升级,那会是什么原因呢?难道是昨天我把系统B的升级文件拖错地方了?这可不是玩笑,如果真是这种情况,估计我要受惩罚了。于是,我忐忑地登上服务器,认真地对比了昨天升级的文件,还好,没有拖错文件,虚惊一场。

时间在不断的过去,我们始终没有找到原因。对于昨天还正常运行的系统,并且没有做过任何代码,配置的改动,为什么今天会出现问题?日志文件没有报错,服务器运行正常,一切看起来都是那么平静。正是这样,我们排查原因的难度就更加大。看着客服业务量不断的损失,我们只能跟负责人申请切换到应急方案。

晚上趁客户不使用系统,项目经理和小伙伴们都加班加点的投入到问题的排查中。后来想想,我们当时的排查是多么的杂乱无章。为了复现白天的场景,每个人登陆多个客户端,模仿多名访客,这种低效的操作是不可能发现问题的,最后还浪费大量的时间。然后我们又排查了代码逻辑,要知道代码是没有变过的,理论上应该不是代码的问题,但我们还是为代码的实现纠结了半天,最后只能是多输出日志,对存在疑问的代码尝试修改,第二天再观察。

众里寻他千百度,答案总在容易忽略处

第二天来到公司,看着群里的反馈就知道昨天的努力是白费了,修改没有起作用,日志照样没有异常输出。项目经理不在,技术经理无力了,我们只能将现在的状况报告给老板,老板当然也很关心这个问题,于是从其他项目组调动大量人力来协助我们排查问题。

人多不仅力量大,经验也多。大家都将自己以前遇到过的情况和此进行对比,有的提出看数据库是否锁表,有的看服务器网络是否异常。于是,从不同的方向,大家都开始忙碌起来。数据库方向的排查结果是没有锁表出现,网络环境通过抓包发现传输的数据有异常,貌似是交换机UDP端口不适配,造成数据包被交换机打回,于是我们申请修改交换机配置。但对于大企业来说,上线系统的很多权限是不会开放给系统开发者的,比如数据库管理权限,交换机配置权限。

在申请权限的过程中,我们继续模拟用户访问系统,在偶然的情况下,观察数据库的小伙伴发现有异常的update操作,该操作很耗时,基本每次操作都要耗时20秒左右。这是很严重的!于是,我们排查该操作的来源和为什么这么耗时,发现该操作的对象表竟然没有主键!对于这样一张经常操作的核心业务表竟然没有主键和索引,真不可思议!在建立了主键和索引后,继续观察该update操作,耗时瞬时减少到毫秒级。然后,我们怀着试一试的态度,重新开放了系统的业务接口,让各省客服人员正常登陆,到下班为止,没有再出现掉线情况。本以为不可能出问题的地方,恰是问题产生的源头。后来才知道,产品的初始化数据库很多表都没有建立主键和索引,这能有多坑爹啊!

每次的坑爹都是积累,都是成长

摊上的这次大事,对于我来说意义还是挺多的,最起码让我认识到系统灾难的预防和应急策略的重要性。

现总结如下:

1、系统要有多个入口,正常的入口,异常情况下的应急入口。比如,正常情况下系统可以接入在线客服,如果出现异常情况,比如客服大量掉线导致不能继续提供人工服务时,需要将访客引导到在线留言,这样不会造成过多的用户投诉。同时,最好能提供一个系统调试的入口,比如在灾难情况下会引导访客进入留言,但我们可以预留相应的url,通过这个url我们可以越过留言,进入人工系统,这样我们可以一边登陆客户端,一边充当访客来进行系统调试(主要利用各省客服的力量)。当然,这些对于我们现在的系统是可以这样做的,但对于其他系统,比如银行系统,电子商务系统,遇到灾难时是不允许在线调试的,这样我们就要维护一个和线上环境同步的测试环境,以便模拟问题。对于需要并发的系统,可以使用LoadderRunner等工具模式并发量。

2、进行自动化服务器监控是必要的。我们现在是人为监控服务器各项指标的,什么时候想起来就去服务器上看看各项指标是否正常。这种做法肯定是不行的,但由于动力不足,一直没有改变。服务器内存,NoSQL内存,oracle表空间和锁表情况,常用文件目录大小,线程池,数据库连接池,网络等参数都需要监控,可以使用免费的企业监控软件,也可以针对重要指标开发相应的监控软件,最好能做到遇到异常即时通知,如短信通知,邮件通知。

3、必要的性能优化。此次问题主要是没有进行数据库优化。常用的性能调优软件,比如JProfile等都可以尝试下。

4、自动化部署。系统补丁的升级最好采用自动化部署。人工的备份和部署是低效的表现,任何能自动化处理的都要自动化。

5、做好灾难的应对策略,对可能遇到的灾难提供相应的补救措施。比如准备备用的端口或主机,应急的系统入口。

6、面对灾难要有冷静的头脑,不能乱了方阵。这次事故由于出现在没有修改代码,日志文件又没有报错的情况,导致我们失去了系统排错的方向。一贯依赖于根据错误信息排查的我们,此时毫无方向。最后借助于其他项目组同事,才打破这个思维定式。现在想起来,如果代码没有问题,前段时间还正常运行,今天却突然异常,那我们可以初步定位为某些资源随时间增长,消耗在不断增加,以至于现在提供的资源满足不了系统需求,或网络环境发生变化(服务器所在网段进行改造等)。然后可以进一步排查,是网络原因?数据库原因?其他基础设施?一步步排查,一步步接近问题的答案。

7、寻找有经验的小伙伴,大家的力量是无限的。

8、顶住客户方面的压力,激活团队的士气,让大家积极地投入到解决问题的氛围中。

今天就先写到这,希望对大家有帮助。以后遇到类似问题再分享吧!解决问题确实需要经验的积累!

报告老板,摊上大事了!

上一篇:用Thread类创建线程


下一篇:Photoshop为高清的人像脸部增强质感