背景
讲一个发生在15年自己身上的例子。
当时负责开发维护整个公司的所有搜索引擎。两年时间内大体同样的方法已经搭建过好几套了。所以被要求再搭建一套的时候本以为不会出现什么问题。结果搭建好运行一段时间请求会超时。
登陆服务器观察到了”too many open files(文件句柄耗尽)“错误。用linux命令可看到:用户可以打开文件的最大数目为65535(linux命令为ulimit -a),已经到极限了。最后观察了系统的内存已经快耗尽了(因为一台机器上同时运行了多个服务)。换了一台内存充足的机器解决了问题。
当时问题解决了,但是问题的原因并不是特别清楚。同时,对于同类问题也没有形成系统性的解决方法,所以总是时不时思考这个问题。
两种分析视角
超时问题从广义上属于性能问题。性能问题有两种问题分析视角:负载分析和资源分析。
负载分析是自上而下的问题分析方法,是从应用角度出发,向操作系统和设备硬件延伸来发现问题。
比如背景中提到的问题,当时就是先看到系统日志报错,进而排查系统的资源情况,最终定位问题的。
资源分析是自下而上的问题分析方法,先使用工具等来发现系统、设备的异常,根据问题向上查找发现问题。
比如背景中提到的问题,一开始看到有超时,可以直接看系统的CPU、内存、磁盘等资源情况,发现资源负载高,进而找到资源和程序的不匹配问题。
四大黄金指标
谷歌的四大黄金指标:Latency(延迟)、Traffic(请求量)、Errors(错误)、Saturation(饱和度)。
一个给定指标是好是坏取决于应用开发人员和最终用户的性能预期。所以在系统基本符合预期情况下,需要测量指标数据作为基线。
比如背景中提到的问题,本质上延迟超过了系统的超时时间。这里的超时时间可以理解为基线。超过基线被认为不符合预期。
再比如大家都知道,在linux系统中,平均负载(load average)用于衡量CPU使用情况,有时候这个值可能飙升到1万。远远超过了CPU的总量。这时候,平均负载不再是使用率的概念,而是不能被处理请求的排队量,也就是饱和度的概念。
方法三反三正
排查问题有三种需要避免的错误方法:街灯讹、随机变动讹、责怪他人讹。
街灯讹相当于查看top(1)的问题,误认为这就是产生问题的原因。记得有次排查fullgc问题的时候发现:使用linux的jmap命令查看应用程序的内存快照,使用最高的是[C,就是char数组最多。而任何的操作,比如序列化反序列化、打印日志都会产生char数组,所以按照这个来分析fullgc问题是不合适的。
随机变动讹是一种实验性质的讹方法。用户随机猜测问题可能存在的位置,然后做改动,直到问题消失。这个方法非常耗时而且可能做出的调整不能保持长期有效。比如一个应用程序的改动规避了一个数据库或者操作系统的bug,其结果是可以提升性能。但当系统升级bug被修复后,程序的改动不再有意义。
责怪他人讹包含以下步骤:
1、找到一个别人负责的系统或组件
2、假定问题是与那个组件相关的
3、把问题扔给负责那个组件的团队
4、如果证明错了,返回步骤1
有的时候责怪他人讹存在着一定的组件自身原因。比如一个组件之前经常出问题,那在看到差不多的现象时第一反应就是那个组件又出问题了。所以维持自身的稳定性和口碑本身就是减少运维的要点之一。
在平时工作中,有三种正确方法非常常用:科学法、USE方法、向下挖掘分析。
科学法采用以下框架:问题->假设->预测->实验->分析
USE方法(utilization、saturation、errors):对于所有的资源,查看它的使用率、饱和度和错误。这是从资源角度出发寻找问题的方法
向下挖掘分析开始在高级别检查问题,然后依据之前的发现缩小关注的范围,忽视那些无关的部分,更深入发掘那些相关的部分。这种方法经常和5Why分析法配合使用。
总结
了解了以上基础知识和方法,回过头来看背景中的问题。
搜索服务出现了请求超时,使用USE方法,查看资源发现了内存使用率100%,出现”too many open files(文件句柄耗尽)“错误。再使用5Why分析法来寻找问题根因:
1、为什么会超时?
因为请求访问到磁盘,磁盘文件句柄耗尽了
2、为什么会文件句柄耗尽?
因为所有的请求内存缓存没有命中,直接打到磁盘上,磁盘资源本身不足,加上请求访问磁盘慢,资源还没释放下个请求就过来,最终资源耗尽了
3、为什么内存缓存没有命中?
因为内存资源被别的服务使用光了
4、怎么解决内存资源被别的服务使用光问题?
换一台资源充足的服务器
大家春节快乐!