正常运行的代码总会出现问题,而且总会以出乎你意料的方式表现出来。
代码的正常运行只不过是不正常的一种特殊情况,不正常反而是常态。
之所以把问题归结为不可能的玄学问题或者偶现事件,是因为问题超出自己的认知范围,应该努力提升自己把这类问题变为可解释和可解决的方案。
思路
通常需要故障排除时,问题已经发生,可以告知相关人员,现在开始解决。
1、顶住压力,先不用理会别人的看法或者想法,相信自己才是最了解这个系统的。
2、恢复系统,这可能有反常理,但是当系统基本不可用时,只有恢复系统了才能静下心排查问题。一般处理优先级是重启服务、调度到其它机器、回滚版本。
3、打开监控指标,观察服务之间的指标是否存在异常,主要是定位服务的什么环节出现问题。
4、打开日志系统,筛选最近一段时间日志,基本日志平台日志量最大的时间段,也就是出现问题的时间段,一般通过日志能够看到更明确的问题。
5、现象基本都知道,重要的是定义问题原因,只有定义清原因才能找到解决方案。
如果是系统自身bug导致,到此为止基本可以定位到问题所在,根据实际情况解决问题。
如果不是系统自身bug等问题,你可能看到只是现象,而不是原因,这会变得复杂,可能还需要其它同学介入。
这里简单说下如何定义故障的现象和原因
通常我们看到的是问题现象,能解决问题现象的方案才是原因。说的简单,很多同学却把问题现象错当成原因。
举几个简单的例子。
- 之所以出现故障,是因为来了一波访问高峰,把服务打挂了,现在已经恢复。外行人看到,前途无量,响应迅速,内行人看了这只是描述了现象,并没有找到根本原因;
- 我看了下服务是 k8s 的探针或者 Linux 服务器把服务 kill 掉了,我需要找基础设施的团队看看原因。这里已经本末倒置,别人基本一脸懵逼,被干掉只是表面现象,具体原因基本是自身服务不正常导致的;
6、记录整个操作过程,方便回滚,不至于精神紧张,忘乎所以。
如果不纠结细节问题,分钟内恢复,基本不会造成什么影响,当然具体还要看服务质量级别 SLA/SLO。
还有一类问题,也不算是问题,忽然就变得不正常了,如下图。
这类问题一般都是由变更或者bug引起,可能通过重启甚至回滚版本都不能起到作用;这时你要分析整个平台最近做了什么变更、对照监控、链路追踪系统是什么环节导致的整个系统不稳定。
当你问题解决完成之后,领导总是喜欢问以后如何避免此类问题的发生,当有人提到利用一些AI外部自动化系统监测系统的稳定性,从而根据实际情况进行自愈的方案时。一定要慎重考虑,因为很多问题都是百年不遇,而且还会留下一个第三方的累赘系统。打铁还须自身硬,问题的解决一定是由内而外的。服务自身做好限流和降级保护,出现问题时,服务能够利用自身的弹性和鲁棒性自愈能力。比如一些数据库当占用内存超过阈值会通过LRU算法进行淘汰数据或者通过系统swap交换到磁盘。
记得之前有个大佬就说过,大厂并不是代码写的多牛逼,而是他们容量规划做的好;压力测试做到位;根据服务承载量网关层面做好限流和保护;在真实环境中不断演练和优化,从而能够从容面对高流量引发的崩溃问题。
见解
问题的发现和解决一定是依赖系统指标表现去判断的,如果你的系统不可量化,那么一切都无从谈起。之前写过一篇监控服务的方法,有兴趣的可以参考:Prometheus Grafana的思考和实践
想办法通过指标量化你的系统,让它可观测,如果不支持,那就改造它,让它支持可观测。
一旦所有系统可以量化了,那么你就可以帮助你快速发现问题,甚至找到系统瓶颈优化服务。平时用到的一些优秀服务,比如redis,清晰的说明自己的数据结构占用内存大小,QPS是多少,甚至压力测试工具都可以摆出来。
这样当服务出现问题,也有其他人帮忙处理问题,否则关键时刻只能靠你自己救火。