告警的本质
没有多少系统的告警是设计得当的。良好的告警设计是一项非常困难的工作。如何知道你收到的告警是糟糕的少次你收到了告警之后,立即就关掉了的不是成天被这些然而并没有什么卵用的东西给淹没常见的告警设置:cpu使用率超过90%,然后告警。这种设置在大部分场合下是没有办法提供高质量的告警的。
高质量的告警应该是这样的:每次收到之后你可以立即评估影响的范围,并且每一个告警需要你做出分级响应。所谓每个告警都应该是,actionable的。
告警的实质可以用下图表明:
告警的实质就是“把人当服务用”。在一些事情还没有办法做到程序化执行的时候,用告警通知人的方式去干预系统达到修正的目的。一次告警就像一次服务调用一样。如果告警了,但是收到告警的人并不需要做任何处理,那么这就是一种DDoS攻击,攻击的是运维的幸福生活。
很多时候,告警通知人去干的事情是真的可以被自动化掉的。比如服务器挂了,换一台上来。在小一点的系统里,可能就是停机一会,人工来处理换一台冷备的机器上去。大一点的系统,因为服务器多了,天天都挂可不行,必须是热备的,系统自动切换到备机。再大一点的系统,因为切换实在太频繁了,故障机的退库,备机的保有都变成了一种管理负担,那么可以和其他的运维流程打通变成完全自动化的系统。只是因为业务处理不同阶段,选择不同的实现策略而已。业务量小,拿血肉当机器用,有的时候更经济而已。当然对于那个被当成机器人来用的哥们来说,生活确实有点不公平。
告警对象
告警对象可以分为两种:
- 业务规则监控
- 系统可靠性监控
对于业务规则监控可以举一个游戏的例子。比如DNF的游戏角色在一定装备的情况下,单次打击的伤害输出应该是有一个上限,如果超过了就说明有作弊的情况。又比如斗地主游戏里一个人的连胜场次是有一定上限的,每天的胜率是有一定上限,如果超出平均值太多就可能是作弊。业务规则监控的不是硬件,也不是软件是否工作正常。而是软件是否按照业务规则实现的,是否有漏洞。也可以理解为对“正确性”的监控。
系统可靠性监控是最常见的监控形式,比如发现是不是服务器挂掉了,服务是不是过载了等等。对于大部分后台服务,系统可以抽象建模成这个样子:
一个DB会依赖于底层的cpu,内存,磁盘等资源。一个Http服务会依赖于底层的DB服务。一个应用会依赖于数个底层的RPC服务。于是又多了几个指标
- 资源A的调用量(比如CPU使用率)
- 资源B的调用量(比如内存分配和释放)
- 资源C的调用量(比如 络发送包量)
- …
这种层次结构,一般来说简单来说可以分为四层:
- 产品策略和营销:它们决定了根本的请求到达的速率
- 应用层(更粗俗一点可以叫web层):最上层的胶水
- 服务层:db,各种RPC服务,以及层层嵌套的服务
- 硬件层:cpu,内存,磁盘, 络
上图的黄线是昨天的值,绿线是今天的值,大部分服务监控的曲线图都长这样。可以得出四个思路:
- 曲线平滑:故障一般是对近期趋势的一个破坏,视觉上来说就是不平滑
- 绝对值的时间周期性:两条曲线几乎重合
- 波动的时间周期性:假设两个曲线不重合,在相同时间点的波动趋势和振幅也是类似的
- 有一个长度可观的坑:当曲线开始回升到历史范围的时候,一般可以确认这个时间段是真的故障了
从这四种直觉展开,可以得出各种或复杂或简单的算法。下面要讲的算法都是非常简单的,无需很高深的数学知识。
基于曲线的平滑性的检测
这种检测的根据是在一个最近的时间窗口,比如1个小时。曲线会遵循某种趋势,而新的数据点打破了这种趋势,使得曲线不光滑了。也就是说,这种检测利用的是时间序列的temporal dependency,T对于T-1有很强的趋势依赖性。业务逻辑上来说,8:00 有很多人登陆,8:01 也有很多人来登陆的概率是很高的,因为吸引人来登陆的因素是有很强的惯性的。但是7.1很多人来登陆,8.1也有很多人来登陆的惯性就要差很多。
基于近期趋势做告警,就需要对曲线的趋势进行拟合。拟合有两种方式,moving average 或者 regression。这两种拟合方式有不同的bias(倾向)。
x是实际值,s是ewma计算出来的平均值。也就是下一点的平均值是由上一点的平均值,加上当前点的实际值修正而来。这个修正的比例,就取决月这个alpha的decay factor的大小。视觉上来说就是ewma曲线是否紧跟实际曲线,也就是平滑程度。
上图中不同的颜色代表了不同日期的曲线。很多监控曲线都有这样以一天为周期的周期性(早上4点最低,晚上11点最高之类的)。一种利用时间周期性的最简单的算法
min(14 days history) * 0.6
对历史14天的曲线取最小值。怎么个取最小值的方法于12:05分,有14天对应的点,取最小值。对于12:06分,有14天对应的点,取最小值。这样可以得出一条一天的曲线。然后对这个曲线整体乘以0.6。如果今天的曲线低于这条参考线则告警。
这其实是一种静态阈值告警的升级版,动态阈值告警。过去静态阈值是一个根据历史经验拍脑袋的产物。用这个算法,其实是把同时间点的历史值做为依据,计算出一个最不可能的下界。同时阈值不是唯一的一个,而是每个时间点有一个。如果1分钟一个点,一天中就有1440个下界阈值。
实际使用中0.6当然还是要酌情调整的。而且一个严重的问题是如果14天历史中有停机发布或者故障,那么最小值会受到影响。也就是说不能把历史当成正常,而是要把历史剔除掉异常值之后再进行计算。一个务实的近似的做法是取第二小的值。
为了让告警更加精确,可以累积计算实际曲线和参考曲线的差值之和。也就是相对于参考曲线下跌的面积。这个面积超过一定的值则告警。对于深度下跌,则累积几个点就可以告警。对于浅度下跌,那么多累几个点也可以告警出来。翻译成人话就是,一下子跌了很多,则很有可能是故障了。或者连续好久都偏离正常值,那么也很有可能是出问题了。
优点:
- 计算简单
- 可以确保发现大的故障,出了告警一定是大问题,可以直接打电话
缺点:
- 依赖周期性的历史数据,计算量大,而且无法对新接入的曲线告警
- 非常不敏感,小波动无法发现
基于振幅的时间周期性

有些时候曲线是有周期性,但是两个周期的曲线相叠加是不重合的。比如上图这样的,曲线整体的趋势是 上的。两个周期的曲线一叠加,一个会比另外一个高出一头。对于这种情况,利用绝对值告
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!