概述
维护现有的软件是每个工程师日常工作中不可缺少的工作,也是基本的技能之一。那么当出现故障后,我们该做些啥?怎么去排查问题?正所谓工欲善其事,必先利其器,针对不同的软件环境所需要的工具也不尽相同。在出现故障时怎么才能保持一个清醒的头脑也至关重要,不过这也来源于自信,来源于平时的积累。
从工作到现在,笔者维护了很多系统,从要求5个9的可靠性的网站系统到现在上万台离线的hadoop集群。离线的hadoop集群故障停机也意味着损失,如停机1小时,则损失为(1/24/365/3)10000(台机器)60000(3年的每台机器的费用)=2.28w元,我们应该尽量降低停机的时间。对于在线应用那肯定是不能停机的,如taobao主站,停机1小时,那则是数百万的损失,且客户会流失。
由于阿里主要的应用是java的应用,笔者接触较多的也是java应用,将从java方面出发讲述一些方法及工具。
克服紧张
这是一个非技术的问题。当故障发生时,怎么做到不紧张呢。笔者记得刚毕业的第一年,有一次发布引起线上问题,当时真的非常紧张。目前笔者也没有好的办法,多经历几次也许会好点,当然如果对系统非常熟悉也会好点。这就要求我们多积累。
一般查询问题的思路
基本的一些问题(分类不全):
- 功能性问题:产生的一般原因是 环境不一致,发布的时候一般就会遇到。如:线上的网络环境,有的master节点配置了vip,部署结构等导致的。查询问题的思路也基本是看是否不一致引起的。
- 性能类问题:对于有中心节点,来得最直接的方式是提高master的机器能力,通过jstack找到性能瓶颈点。slave节点是否可以增多机器来解决
- 跟业务数据有关系的问题:在特定场景下发生的,如:有的用户在map中处理每行记录时调用了DNS导致job相当慢,reduce数据发生倾斜。
- 数据不一致:业务系统中经常碰见,此类经常需要对比不同数据系统的数据。
- 有一些问题很直白,基本快速可以查询。对于一些很难直白知道原因的,最大招数就是debug。但是线上环境不可能或者不能debug,所以,最好还是在测试和开发环境模拟其线上场景,不断探测直到重现,再查询原因。
保留现场及一些常见工具
由于,我们经常处理的措施是重启系统或者回滚系统,那一般当时出问题的场景也就破坏了。为了保留环境,最好有一些监控的系统,能把大部分的信息保留下来,方便定位问题及重现。一般情况下,一些瞬间的状态需要自己手工执行,例如:
- 保留日志,很多系统重启后就会冲掉以前的日志。系统中一般会存在很多关键的日志,其中出现ERROR日志尤其注意。 linux的日志在 /var/log/messages中。
- 一般需要三次jstack,看是否有性能瓶颈点,看堆栈 线程数是否正常。
对于内存不足,一般会在日志打印相关的内存溢出异常。
jstat -gc -h5 pid 1000 1000
- 一般三次sudo netstat –anlp 保留现场
- dump堆栈用mat分析
jmap -dump:live,format=b,file=heap.bin pid
- 常用的是分析内存溢出,特别地,可以用 OQL语句,查询相关的对象,分析其值。
如:
OQL:select * FROM "org.mortbay.jetty.Request"
- tcpdump相关的包:如:dump 来自host为10.148.184.141 本地网卡bond0 的非8031和非8030的端口的包,
sudo tcpdump ip host 10.148.184.141 -i bond0
and ! tcp port 8031 and ! tcp port 8030