写在前面:前段时间,朋友给我说了一个她亲身经历的某知名企业面试故事,面试结束感觉自己已脱了一层皮。。。面试官的问题并不刁钻,但是却是步步紧逼,而且有点类似拜占庭将军问题,只是拜占庭将军问题是所有的假设都不可靠,面试官的问题是,啥也不知道,也没有规律,又严重,又不知道怎么引发。。。无从下手的一个棘手问题,如何协助开发定位分析,细想想,起始无非是先排除服务器相关可能,然后再一步步剥离,将嫌疑犯范围缩小,尽可能帮助研发发现并定位到罪魁祸首,当然也许不仅仅是一个元凶。
问题是这样子:某天,发现一个问题,会引起程序崩溃,但是又不是必先的问题,现在又处于上线前非常时期,没有大把时间去慢慢重现,这个问题研发也看不出所以然,但是会出现,用户体验很差,需要段时间呢定位出来,作为测试,如何协助开发定位并找到问题根源(大概是这个样子的,具体忘记了,反正就是问题不必现,严重,无规律,还必须给重现),其实我觉得,针对具体问题需要具体对待,问题出现了,而且一头雾水的情况下,不要自乱阵脚,我们看不出问题,但是可以用排除法一项项缩小问题范围,遇到问题的头10分钟是最重要的,也是最关键的。
一、尽可能详尽的描述问题前因后果
切勿在遇到问题就开始手忙脚乱,记住磨刀不误砍柴工,首先我们要知道现在运行的这个服务器有多少已知情况,有多少东西是可以辅助问题分析的。
必须要搞清楚的问题有以下几点:
- 故障什么时候发现的
- 故障是否可以重现
- 故障的表现形式是什么(无响应、报错、宕机等等)
- 故障出现是否有规律可循(时间点规律、资源占用规律、引发规律)
- 最后一次平台内容更新是什么(代码、服务器、容器、pck等)
- 故障影响的用户群是什么样的(特定的?随机的?)
- 故障出现时在运行什么程序
- 是否有监控平台可用(任何监控平台都可以)
- 是否有日至可查(服务器日志,容器日志,代码日志)
- 服务器资源占用情况(内存、网络I/O、磁盘I/O、交换、CPU、网络、磁盘、进程、负载等)
还有空余的内存吗? 服务器是否正在内存和硬盘之间进行swap?
- 服务器最大的负载来自什么地方? 平均负载是多少?
服务器是几核的? 是否有某些CPU核负载过多了?
二、服务器在出问题的时候有谁在
#who ----查看有谁在登录
#last -x ----查看用户登录历史#lastlog ----简单查看所有用户最后一次登录时间
查看有谁在,哪些用户执行了哪些操作,很重要,有可能就是有些用户在调试程序导致的问题。。。或者多个用户同时更新程序。
三、之前执行过什么操作
#history ----查看服务器上执行过的历史命令
#cat /home/username/.bash_history ----查看某用户在服务器上执行过的历史命令如果是要查询是谁操作过文件可以
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/profile
然后用history 查看
如果是需要查询被动过的文件可以
find /xx -mtime -2 在/home下查最近两天内改动过的文件
find /xx -atime -1 查1天之内被存取过的文件
find /xx -mmin +60 在/home下查60分钟前改动过的文件
find /xx -amin +30 查最近30分钟前被存取过的文件
xx 代表你需要查询的目录。你也可以直接用 / 但是这样查询量太大。。影响资源使用。
查看在出问题的前后都执行过什么操作,有没有高危操作,这样子可以快速排除一些不必要的麻烦,有时候,问题出现也许仅仅是执行某个操作间接引起的,所以仔细辨别很重要。
四、现在还有哪些进程在运行
#ps aux ----显示所有正在运行的进程
#pstree -a ----已树状显示正在运行的进程
#top ----查看进程及其他附件信息
查看正在运行的进行以及运行的用户,可以根据业务逻辑之间的关系,看看哪些程序出现了问题,把问题模块化。
五、硬件
#lspci ----显示系统中所有PCI总线设备或连接到该总线上的所有设备的工具
#dmidecode ----输出服务器所有硬件信息
#ethtool ----查看网卡,网卡是否设置好? 是否正运行在半双工状态? 速度是10MBps? 有没有 TX/RX 报错?
排除硬件的原因很重要,网卡,raid卡,备用电池、内存条,硬盘的原因都可能引起故障,通过上面的命令可以查看网卡运行是否正常,工作状态是否合理,raid卡是否OK,内存条数量与实际内存是否一致,硬盘数量大小与实际硬盘是否一致,是否有硬盘不可读等。
六、挂载点和文件系统
#du -sh ----磁盘空间使用情况
#df -h ----磁盘空间使用情况(主要和上一个命令结果对比,如果某文件被删除,但是句柄还存在,没有被清空,在这个命令中将会被统计,上个命令中不会统计)
#mount ----一共挂载了多少文件系统(文件系统格式、文件系统权限、文件系统模式)
#pvs ----查看物理卷信息
#vgs ----查看卷组信息
#lvs ----查看逻辑卷信息
#cat /etc/fstab ----查看文件系统分区信息
挂载了多少文件系统?有没有专用文件系统?磁盘空间是否使用完了?文件系统格式是否支持动态扩容?
七、网络、内核和中断
# sysctl -a | grep ...
# cat /proc/interr
# cat /proc/net/ip_conntrack /* may take some time on busy servers */
# netstat
# ss -s
你的中断请求是否是合理的分配给CPU处理,还是会有某个CPU的核因为大量的网络中断请求或者RAID请求而过载了?SWAP交换的设置是什么?conntrack_max 是否设的足够大,能应付你服务器的流量?在不同状态下(TIME_WAIT, …)TCP连接时间的设置是怎样的?
如果要显示所有存在的连接,netstat 会比较慢, 你可以先用 ss 看一下总体情况。
你还可以看一下 Linux TCP tuning 了解网络性能调优的一些要点。
八、系统日志和内核消息
#dmesg ----查看开机信息/打印或控制内核环形缓冲区信息
#less /var/log/message ----所有开机系统发生的错误基本上都记录在这里
#less /var/log/secure ----记录登录系统存取数据的文件
#less /var/log/auth ----记录用户认证日志
#less /var/log/cron ----记录crontab守护进程crond所派生的子进程的动作
#less /var/log/syslog ----环境运行过程中的告警信息
#/var/log/xferlog ----记录FTP回话,显示用户像FTP服务器或者从FTP服务器拷贝文件的日志
查看错误信息,硬件错误,文件系统错误,连接数错误等等,所有错误信息都可以和发生故障的错误时间点对应起来,进行分析。
九、定时任务
#ps -ax | grep cron ----查看定时任务是否运行
#for u in `cat /etc/passwd | cut -d":" -f1`;do crontab -l -u $u;done ----查看系统中所有用户的定时任务
#crontab -l ----列出当前所有调度任务
主要查看有没有定时任务过于频繁的执行,是否是某些用户提交了隐藏的定时任务,在出现故障的时候是否有某个定时任务正在执行等。
十、应用系统日志
这个就要和环境对应查看了,比如我们环境是Linux + Apache(tomcat、wildfly) +Nginx + Mysql +PHP
- Apache(tomcat、wildfly)----容器访问和错误日志
- Mysql----直接在mysql.log里面找错误信息
- PHP-FPM ----直接查看其日志
- nginx ----查看是否漏掉了啥配置,导致用户可以直接攻击服务器,或者查看nginx的日志,查看是否有可用报错信息
- HA-Proxy----查看负载均衡后端健康状态,队列大小等
通过对部署的环境下容器进行检查,不仅可以查看进程是否正常,还可以看到一些容器配置是否合理,是否有需要的文件没有找到导致异常或者是文件内容读取错误导致?对mysql日志进行查看,可以初步排除或者确定,数据库操作是否有问题,是否引起连发反应,是否有存储过程执行错误,方言设置不正确,语句插入错误或者高并发导致数据库执行操作锁表?nginx日志直接查询错误码即可,或者查看某些接口调用次数是否过于频繁“GET /task/showContent”关键字搜索,找到调用最多的接口,并统计报错接口,并可以通过接口并发量查看是否是并发过多导致程序过载?nginx配置是否合理,有没有循环嵌套访问导致一直刷屏直至nginx崩溃?有没有端口冲突?
总结
十分钟,我们对这个问题的情况可以说是已经弄清楚了,那么问题出现在哪里,和什么有关,是因为资源引起的?还是数据库索引不当,进程过多,内存溢出,堆栈错误。。。就可以有针对的分析下去了,排除了环境原因的话,问题的根源也许就在眼前。
当然,在搜索数据的同时,我们还可以从自己的专业角度去对问题进行一定的猜测与重试,对业务逻辑进行整理与异常尝试,梳理出可能点,协助研发定位问题并尽快重现问题。双管齐下,效率永远是更胜一筹的。