前言
说起线上故障,程序员应该都经历过,从故障处理恢复过程中我们能快速提高。踩坑多了,慢慢也就成了大牛。这道题也是大厂的面试官们特别喜欢问的问题之一,从候选人对这道题的回答过程中,面试官至少能获取到两个方面的反馈。第一是你平时负责的项目是不是核心项目,如果你说你负责的是后管系统,出了问题重启就OK了,那结果只能是出门右转了。第二是候选人系统化处理问题的能力。你是如何快速止血;如何一步步快速定位到具体问题;故障前的准备工作是否充分,风险点有没有紧急应对方案。
下面我们就一起来聊聊线上故障的排查过程
快速止血
在分布式系统环境中,最重要的就是快速止血。在互联网公司呆过的同学知道,恐怖的复盘大会往往第一个问题就是为什么故障花了半个小时,业务都投诉了才知道。或者是为什么花了15分钟才知道是慢SQL问题,被按在地上摩擦的不要不要的。
原因是在分布式系统中,故障很容易产生“多米诺骨牌效应”。比如一个基建服务因为一个慢sql导致请求响应变慢,就会导致上游的请求堆积,线程无法释放,进而导致上线的系统也变的很慢,出现大量error。这个雪崩过程有时候很快,到时候测试,运维,上游系统的负责人在各种电话,信息轰炸你的时候,这时候的你肯定是
怎么办?如果问题定位了很长时间还没定位到,那就只能先用杀手锏了:
- 重启 系统不可用时先重启,先保证系统的可用性,具体功能问题还要继续定位,重启几分钟又出现大量error就尴尬了
- 限流 重要接口要提前准备好限流配置,随便可以动态更改接口QPS
- 线上回滚 如果前一天刚有上线动作,那十有八九就是上线导致的,这种情况如果问题暂时没排查出来可以先回滚,然后组织一堆人去扒新提交的代码吧
- 紧急扩容 首先服务必须是无状态的,支持动态扩展,而且瓶颈必须在应用服务,如果瓶颈在DB或者在别的地方也没办法
故障排查过程
前面说到如果前一天有上线,然后出现故障回滚了,这种情况十有八九是回归测试不彻底,影响之前的逻辑了,最坏情况就是一堆人一行行去扒代码。现在我们讨论的是如果生产服务变得很慢,error告警不断增加的情况下怎么处理?
- 服务监控 系统高可用设计手段中很重要的一条就是服务监控 ,系统上线了不能裸奔,不然怎么死的都不知道。安利一下美团开源的CAT监控系统,CAT能实时监控各个指标,各个链路事件。包括服务器的CPU负载,JVM内存,GC信息,线程信息,慢URL,慢SQL,请求响应耗时平均线、95线、99线,以及配置单位时间内多少服务error告警等。
- 故障排查命令 面试官经常喜欢问候选者线上故障有哪些排查命令,怎么去排查的。一般是先整体后局部的顺序来排查
1.查询整机 首先通过top命令查看整体情况,比较重要的指标有Load AVg,CPU usage,每个进程的CPU和MEM。
也可以通过uptime查看精简版
2.CPU 通过vmstat工具查询CPU的情况,vmstat包含两个参数,第一个参数是采样隔间时间,但是是秒,第二个参数是采样次数。如:
vmstat -n 2 3
表示每隔2秒采样一次,一共采样3次
- proces
- r 运行和等待CPU时间片的进程数
- b 等待资源的进程数
- cpu
- us 用户进程消耗CPU时间百分比,如果长期大于50%,可能存在CPU泄漏的危险,需要优化程序
- sy 内核进程消耗CPU时间百分比
3.内存
free
free -g
free -m
一般应用程序可用内存/系统物理内存<20%代表内存不足,需要增加内存
4.硬盘
df -h
5.磁盘IO
iostat -xdk 2 3
大部分场景下如果系统慢,一是CPU导致,还有一个就磁盘IO。常用的排查工具用iostat,参数含义跟vmstat一致
6.网络IO
ifstat l
ifstat命令如果不支持需要安装,可以查看各个网卡的in,out;观察网络负载情况;网络情况是否正正常等
CPU占用过高分析思路
- 先用top命令找出CPU占比最高的进程
- 通过ps -ef命令或者jps(java进程)命令进一步定位这个占用CPU最高的进程是一个什么后台程序
- 定位到具体线程
ps -mp 进程ID -o THREAD,tid,time
-m表示显示所有的线程,-p进程使用cpu的时间,-o后面是自定义参数
- 将定位出来的线程ID转换为16进制
printf "%x\n" 线程ID
- 定位到具体代码
jstat 进程PID | grep 16进制线程tid
以上排查过程读者可以在本地跑一个死循环的程序,跟着步骤one by one分析一遍,肯定会有所收获
系统上线前的风险评估及应急方案
为了出现故障时能够有条理的处理,事先必须有完善的准备工作。
- 系统监控,再次强调,线上系统不能裸奔
- 设置故障等级,阿里是根据影响用户量来定故障等级,不同的故障等级有不同的止血时效要求,规定时间内没止血就会上升,触发更高级的流程
- 故障演练,核心接口压测必不可少,像秒杀系统,瞬间大流量怎么处理,redis挂了怎么处理,DB CPU快打满了怎么处理,都要事先演练好,准备好止血或者降级job或脚本
故障复盘
终于说到最核心的了,对程序员来说,每次线上事故踩坑都是一次大的成长,为了茁壮成长,事后复盘必不可少
常见的复盘流程三部曲
- 故障处理过程,从发现故障到处理完故障详细记录几点几分分别干了什么事,把事故从发生到解决的所有细节记录下来
- 故障原因分析,说明故障的原因和分析报告,简单一点就是定事故责任人了
- 后续整改TODO
总结
故障排查过程就讲完了,你平时工作中碰到过哪些印象深刻的故障,事后是怎么复盘的,欢迎留言交流。笔者的一个同事说起在前东家的一个故障处理的趣事。半夜系统割接上线后,流量灰度切换过来后没过久系统开始疯狂告警,然后一堆大佬坐着同事后面看着他处理故障,同事紧张的查询数据库select单词都敲不对。
感谢关注
可以关注微信公众号「 回滚吧代码」,第一时间阅读,文章持续更新;专注Java源码、架构、算法和面试。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。