过年线上出问题怎么办,还在担惊受怕?聊一聊如何精准地配置告警策略

对于新手来说,有些事会感到很棘手、很困难,但对于老司机来说却轻而易举,就像砍瓜切菜一样简单。两者唯一的差异只是经验多少,而非能力高低。只要掌握了相关经验技巧,解决这些问题就会变得轻松自如。

如何精准配置告警策略,识别出异常流量?首先介绍,正常监控曲线分哪几类,有哪些特征,然后再介绍如何配置各分类的告警策略。

周期性波动

周期性波动流量是最常见的,例如订单的售卖量每天随时间周期性有规律的波动,如下图所示。包括外卖、打车等业务都明显的高峰时间段,由于用户量众多,订单的整体波动是连贯,并非突增突降的。其他场景包括短视频、内容类平台,例如抖音快手知乎等业务由于用户的使用习惯,也一定会存在高峰期和低峰期,由于用户量巨大,在统计上就会出现极具规律性的周期性波动特征。

大流量、长周期、有规律性的周期性波动、无规律性尖刺

如上图所示,系统流量每天随时间规律性的波动,几乎每天的曲线波动规律相同。同时曲线没有尖刺,即正常情况下,不会在周期性波动上出现尖刺,系统流量又比较大,波动比较平稳。

一般情况下,互联网业务中,有相当多的业务场景监控流量,具备上述特征的,是比较常见的。

日同比、周同比、月同比

首先要明白,系统绝大部分时间段都是正常的,只有很少的时间段是异常的。将当前时间和历史上的某一天的同一时间进行对比,能有效发现异常。例如 昨天 11 点订单量 1000,今天订单量才 300,日同比下降 70%,这就说明今天的流量可能有异常!周同比和月同比类似。

然而仅仅使用日同比可能并不合适。就拿掘金阅读量来说,周末的阅读量可能只有工作日的 1/3,使用日同比就会出现如下情况:周六相比周五日同比大幅下降,周一相比上周日大幅上升,解决方式就是:叠加日同比和周同比,因为周同比不受工作日影响。

其他场景包括,寒暑假因素,在寒假期间系统的流量上升明显,例如游戏业务或者短视频业务在寒暑假的流量会增加很多。这个时候月同比的波动就会比较明显,这是正常的情况,无法说明系统有问题。

然而受运营策略波动较大的场景使用X同比策略,就会出现较多的无效告警。 例如平台有很大的优惠调整,例如双 11、双 12、各种平台的营销策略会导致流量大幅上涨。 如果只是偶尔出现大的营销策略,可以在运营活动开始结束时,人工调整告警策略,如果平时经常性的调整运营策略,例如几乎每周都会有运营策略调整,那么周同比和月同比的变化就会非常大,会经常性的出现无效告警。

此时只使用 X 同比策略就无法有效发现问题,为什么呢?因为无效告警多了以后,大家对于告警就会变得麻木,就不会重视告警,等真正的异常告警报出来,会被大家忽略掉。所以告警策略一定要十分精准,不精准的告警策略会导致较多的无效告警,这等同于没有告警

告警要十分精准,无效告警多了大家就会麻木,这等同于没有告警。

要解决日、周、月同比不准确的问题,就需要使用波动告警!

如何配置波动告警

这是本文的重点部分

波动告警有很多种计算方式,例如最简单的波动告警,最近1 分钟和 前 1分钟的售卖量进行对比,例如11:00 售卖量 1000;11:01 售卖量 1010,那么最近 1 分钟的波动比例是1010/1000 = 1%。 既然如此,超过 5% 波动就告警是否 OK 呢?不然,有两个地方值得推敲。

  1. 为什么告警阈值是 5%,而不是 10%?如何确保合理配置阈值,既不误告、也不漏告?
  2. 如果曲线正常情况下也会出现极值波动,这会出现大量无效告警,如何优化?(无效告警多,等于没有告警)

以上两个问题是精准配置告警的难点!

问题 1 的难点在于如何精准确定告警阈值? 一定要避免拍脑袋的方式确定阈值,例如随便拍了1 个数------ 5%,出现误告了就调高一点,不断地调整,最终系统不误告了,但是真正的异常也被大的阈值过滤掉了。这是大多数人配告警的真实写照。

正确的做法应该是:基于历史数据和波动计算公式,绘制波动曲线图,找到历史数据中波动比例的特征,根据特征针对性的配置告警策略。

回归历史数据,绘制波动折线图

例如计算 1 分钟的波动,可以将每 1 分钟的波动比例绘制成折线图,观察折线图的特征,例如下图就是 1 分钟的波动比例折线图

可以看下图,第一条曲线是监控曲线,第二条曲线是第一条曲线的波动曲线。可以看到曲线 1 是明显周期性规律性波动,曲线增长平缓,基本没有突增突降等尖刺。曲线 2 反映的是每一分钟的波动比例,放大来看,绝大部分波动在 -15% - 15%之间。那么是否可以配置上下 15%的波动告警呢?不可以,正确的做法是,多回归历史数据,这张图只反映了某 1 个天的波动情况,要多回归历史数据,得出最精准的阈值。

选择最合理的波动公式

如上图中,最近 1 分钟的波动曲线一直在上下波动,没有任何趋势可言。这并不是最优的波动计算公式,因为 1 分钟这个区间太小了,受极值影响较大。

更准确的办法是 最近N 分钟平均值波动。 例如最近 2 分钟和前 2 分钟的平均值之间计算一个波动。这能反应系统在 2 分钟一个周期的增长情况,有利于平抑极端值的影响。

波动比例 M = (Pn + Pn-1)/(Pn-2 + Pn-3);

接下来我们看看2 分钟和 4 分钟的平均值波动折线图。

  1. 曲线 1 是 1 分钟波动曲线,上蹿下跳,基本没有规律
  2. 曲线 2 是 2 分钟波动曲线,有点规律,但是不够明显。
  3. 曲线 3 是 4 分钟波动曲线,有明显的规律,上涨和下跌时间段的波动变化区间更小,更有规律。

什么算更有规律呢?

先说没有规律的,曲线 1 (1 分钟波动)就没有规律可言。曲线 1 在上涨和下跌两个时间段内,波动比例都是上蹿下跳,没有明显特征。只能发现1 个特征------------波动比例不超过 15%,但这意义不大。因为如果系统出现异常增长,每1 分钟增长都是 10%(7 分钟流量翻一倍,已经很快速了!),如此高的增长比例也不能触发 15%的告警阈值,那么就会出现漏告的情况!这个特征过于粗糙,等同于没有!

在上涨时间段,如果波动比例在一个小的、确定的区间内,就算有规律。在下跌区间,波动比例也在一个小的、确定的区间内,这也说明有规律。例如曲线 3 可以得出结论:

  1. 在第一个高峰期波动比例更大,4 分钟波动增长达到15%。
  2. 第二个高峰期波动比例要小,4 分钟波动增长最多不到 10%。
  3. 在高峰期增长区间以内,4 分钟波动几乎不会出现下跌。
  4. 在高峰期高点以后,下跌区间内,4 分钟波动最大的下跌比例不会超过 5%,增长也不会出现 5%。

通过这个曲线图,我们可以发现很多规律,针对上述 4 个规律,就可以配置告警策略。例如

  1. 在第一个高峰期时间段内,4 分钟波动超过 15% 即告警(根据更多的历史数据,适当增加,例如18%)

  2. 在第二个高峰期时间段内,4 分钟波动超过 10% 即告警。这样能发现晚高峰更迅猛的增长异常。经过我回归历史数据发现,几乎每一天的波动折线图都极为相似,不会出现阈值差异较大的情况,为什么呢?这就是统计学的魅力,在没有其他重要条件干扰情况下,只要统计样本够大(互联网大流量场景),就会得出相同的统计结论。

  3. 在高峰期如果出现 4 分钟波动下跌,即告警。这样能发现增长期出现异常下跌的情况!并且 4 分钟相比 1 分钟,周期更长,排除了极值的干扰!

  4. 在下跌区间波动较小,可以配置上下不超过 5%的波动告警。这样能发现下降区间出现快速下降,或者异常上涨的情况。

针对不同时间段的波动特征,配置针对性的告警策略,就能更精准地告警! 能减少无效告警,也能做到不漏告!

初步总结下 配置更精准的告警策略分 4 步

  1. 要选择合理的波动公式,这里我推荐使用 N 分钟平均值波动就行。
  2. 选择合理的统计周期,可以绘制多个时间长度的波动图,比较一下 周期长度设置多少,更具有特征,一般而言统计周期越大,波动曲线越有规律性,越能平抑极值的影响。
  3. 寻找波动曲线的特征,不同的时间段一般会有不同的特征。例如高峰期上涨时间段,波动比例特征 0% < 波动比例 < 15%;下跌时间段:-5% < 波动比例 < 5%。
  4. 多回归历史数据,配置更精准的告警策略。例如回归昨天、上周、上个月多天的历史数据!

统计周期越大,越容易漏掉一些小异常case

道理很简单,某些情况下,系统出现较小的异常 case,例如主从延迟较大,查询接口的成功率出现下降,在流量曲线上体现是 波动较大,正常的流量增长是平缓的,此时由于有异常,流量曲线上蹿下跳。

如果统计周期配置时间过长,例如 4 分钟,可能会漏掉这些问题。因为 4 分钟的平均值已经平抑了极值影响,即在 4 分钟周期内,波动比例确实没有问题。但是更小的时间周期内,系统确实出现了问题。例如下图,绿色曲线出现了明显的波动,但是 4 分钟平均值仅仅下跌了 3%,没有达到告警阈值。如果使用 2 分钟波动,就能更好的发现这种小规模的异常 case。(这个 case 中,2 分钟波动下跌出现了 10%,4 分钟为 3%)。

所以说并不是统计周期越大,告警配置越精准。而是应该针对系统流量,选择一个适合的统计周期。一般情况下

流量越大,系统曲线越平稳,越应该选择更小的统计周期。流量越小,越应该选择更大的统计周期。

在统计学上,样本数据越大,统计结果越准确,结论越恒定,可信度越高。样本量过小,越容易出现极值,统计结果越不准。

接下来具体聊一下,如何绘制波动折线图。

如何绘制波动折线图

主要分为 3 个步骤,

  1. 准备原始的监控数据。例如每分钟的监控数据
  2. 根据不同的波动计算公式,开发工具。计算每分钟的波动比例
  3. 将每分钟的波动比例序列,导入都 Excel 中,在 Excel 绘制相应的折线图

准备原始数据

一般情况下,各个公司的监控系统都有原始数据,将每分钟的监控数据拷贝出来,放到工程文件中。

开发相应的工具,读取这个文件。

开发工具读取文件

开发工具,计算波动比例

例如下面的一段代码,使用 bodong 方法,输入监控数据文件名,m 为 4,n为 2,即统计2 分钟的波动比例, 如果输入 m=2, n=1,则统计 1 分钟的波动比例; 输入 m=8, n=4,则统计 4 分钟的波动比例。

波动比例计算完成后,会写入到一个文件中,文件命名可以在输入文件名基础上加后缀,拼接周期等。

ini 复制代码
public static void bodong(String filePath, int m, int n) throws Exception {
   URL url = TestReverse.class.getClassLoader().getResource(filePath + ".txt");
   File file = new File(url.getFile());
   List<String> contents = FileUtils.readLines(file, "utf-8");

   StringBuilder stringBuilder = new StringBuilder();

   for (int i = m - 1; i < contents.size(); i++) {

      try {
         int sumPre3 = sumPreNM(contents, i - (m - 1), i - n);
         double avg = sumPre3 * 1.0 / (m - n);

         int sum3 = sumPreNM(contents, i - (n - 1), i);
         double avg3 = sum3 * 1.0 / n;

         stringBuilder.append(String.format("%s\n", avg3 / (avg)));
      } catch (Exception e) {
         System.out.println(String.format("第%s行数据有问题", i));
         e.printStackTrace();
      }
   }
   FileUtils.write(new File(url.getFile().replace("txt", "out")),
         stringBuilder.toString(), "utf-8");
}

public static int sumPreNM(List<String> contents, int start, int end) {
   int sum = 0;
   for (int i = start; i <= end; i++) {
      String[] kv = contents.get(i).split("\t");
      int k = Integer.valueOf(kv[0]);
      int v = Integer.valueOf(kv[1]);

      sum += v;
   }
   return sum;
}

使用办法

java 复制代码
@Test
public void testOrder1111_4_2() throws Exception {
   bodong("1111_order", 4, 2);
}

@Test
public void testOrder1111__2_1() throws Exception {
   bodong("1111_order", 2, 1);
}

拷贝波动比例数据,导入到 Excel 中

将波动比例的数据拷贝到 excel 中,在 excel 中勾选数据,选择插入折线图,excel会自动绘制折线图。

短周期的周期性波动

除以上最常见的周期性波动,还有其他周期性波动流量,例如定时任务导致的周期性波动,这种周期性波动一般是短周期波动,例如 10 分钟一个周期的波动。这种流量,在监控曲线上,曲率非常大,例如下图的曲线是直线上升或者直线下降。

针对特征为:短周期、剧烈的、曲率变化大的周期性波动,一般不需要关注其曲率变化,它经常性的突增突降是正常现象。无需为这种曲线配置波动告警,没有意义。这种曲线只需要配置一个阈值告警即可,例如有定时任务每 10 分钟执行 1 次,会导致 cpu 升高,可以配置 cpu 使用率在 10%-50%的阈值区间告警,只在超过 50%的极端高负载情况下告警即可。 如果是业务流量的周期性波动,可以配置曲线在某一个大的阈值内即可。

短周期、剧烈的、曲率变化大的周期性波动,只需要配置阈值区间告警。

无规律的尖刺波动

例如下图这种无规律的尖刺流量。需要先确定尖刺的原因,再定夺是否告警。假如这个尖刺是异常情况,例如上游传参有异常,系统会上报异常监控。正常情况下,异常监控流量长期为0 ,当告警策略配置 超过 0(或者 10)告警,就能准确是识别异常流量。

告警的二次加工

也有比较棘手的情况,如上图这种异常尖刺。假如大多数情况下,曲线出现尖刺是正常情况,如何识别异常呢?这就需要具体问题具体分析了,我提一个想法。

  1. 出现流量尖刺就告警
  2. 有专门的 MQ 接收告警,在MQ 消费者中,查询系统其他数据,验证是否有异常。

例如售卖量的尖刺可能和秒杀有关系,平台上的大商家或自营门店可能会在某个时间段开启秒杀,有非常大的优惠刺激用户下单,这导致售卖量出现较大的尖刺。 此时系统在收到尖刺告警后,查询对应商家的售卖量,或者查询最近几分钟售卖量靠前的商家。找到对应的商家后,查询商家是否有参与秒杀活动。 将以上信息和告警汇总到 对应的群里,这样能帮助快速定位问题。

这种思路是:收到尖刺告警时,不立即告警出来,而是系统汇总相关的数据,自动判定是否有异常问题。将相关的结果汇总到群里,方便排查和定位问题。

因为这种告警策略开发和维护成本比较高,所以应根据监控曲线的重要程度,决定如何做。

恒定不变的监控曲线

一般接口调用的成功率或者失败率是长期恒定不变的, 这种监控曲线很好配置告警,只需要配置阈值告警即可,例如成功率低于 99%就告警。 如果上线发版期失败率比较高,可在发版期设置更高的失败率告警阈值。监控平台可以打通部署平台,遇到接口失败率较高的告警,查询该系统是否正在发版上线,帮助工程师排查定位问题。

其他情况

流量过低

根据个人经验来看,监控曲线的告警策略和监控流量的大小是密切相关的。假如一个监控曲线,每分钟量级不到 20,这种曲线波动会非常大,所以无法有效配置日同比、周同比、波动率告警。

这种情况下,应该分两种策略监控。

针对异常增长,可以配置阈值监控,在不同的时间段,配置不同的告警阈值,例如平常每分钟不超过 20,可以配置每分钟不得超过 50的监控。

针对异常下跌,可以配置最近 10 分钟,流量低于 5 的次数不得超过8 次; 或者配置最近 10 分钟,流量为 0 的次数不得超过 10 次。(即 10 分钟没有流量,也可以配置半小时,根据业务场景自行决定)。

流量较低

流量较低的情况,一般是 每分钟 120 个左右,即 QPS=2 时,可以配置波动率告警。 但是由于流量比较低,需要配置较大的时间周期,否则告警不准确。具体的方法,可以参照 【如何配置波动告警】章节所说,尝试绘制多个周期的波动折线图,直至找到最有规律的周期长度。

认识监控告警的重要性

流量异常和线上问题,也许你不 care,但是领导很 care!

在项目上线以后的运营阶段,关键要确保系统的稳定性,要求能迅速识别出线上问题。其中,稳定性的抓手之一是全面配置各种监控图表,监控内容包括系统首页和入口流量、提交订单、支付、履约以及结算等各个环节的流量监控。此外,系统核心链路上的各种接口成功率、失败率等也需要进行全面监控,同时还需要监控服务器核心性能指标,例如CPU、内存、网络、磁盘、应用线程数、应用内存以及GC等等。

只需全面地配置监控大盘,即可保证在故障发生后,通过查看监控大盘,快速定位问题的源头。

老板可以安排专人 7 x 24小时盯死在电脑旁,目不转睛的看着监控,直到发现问题。当然再狠心的老板也不会这样压榨员工。有更好的办法第一时间发现问题------------通过配置监控告警策略,让监控系统 7x24 盯着监控,有问题就报出来(通过 IM、短信、电话等)。

流量异常和线上问题,也许你不 care,但是领导很 care!

对于线上问题和薅羊毛等异常流量,领导会更关心。因为出了薅羊毛等类似问题,领导是第一责任人,而非基层员工。大头兵一年到头能出几次线上事故,顶多两三次。但你想想,假如领导有十个下属,把所有人的线上事故累加起来,是不是每周都会有线上事故,领导的头会不会很大!

所以领导一般更重视稳定性问题,更care监控告警的稳定性建设!

工作就是帮领导解决问题,代码写的好看有什么用,领导又不 care

工作嘛,领导让干啥就干啥,领导重视的问题就要优先解决,打工挣工资就是挣一个窝囊费。既然领导更重视稳定性问题、更重视监控告警问题,我们就要优先解决这类问题。代码写的再好看有什么用呢,领导也不关心啊(而且大家的代码水平都差不多,能力上很难分出大的差异),代码写的再好看,只能孤芳自赏,新人接手你的代码还是会喷你写的挫。

监控告警这件事,大家普遍不重视。在学会如何精准配置告警前,要首先改变观念,从做我喜欢的事情(写出更优雅的代码),转变为做领导最重视的事情(领导重视监控告警),甚至抢着去做(做到这样很难)。只有这样,才能受到领导的认可和重视......

总结

本文最重要的有两点

  • 正确认识 精准配置告警 这件事的重要性。 转变观念,做领导认为最重要的事,而非你认为的事
  • 学会如何配置波动告警,回归历史数据,绘制波动折线图
    • 选择最合理的波动公式
    • 选择最合适的统计周期。统计周期越大,越容易漏掉一些小异常case。统计周期越小,波动越剧烈,没有规律
    • 学会绘制波动折线图。三步 1)收集原始监控数据 2)开发波动计算工具 3)导入 Excel,绘制图表
相关推荐
努力的小雨41 分钟前
还在为调试提示词头疼?一个案例教你轻松上手!
后端
魔都吴所谓1 小时前
【go】语言的匿名变量如何定义与使用
开发语言·后端·golang
陈佬昔没带相机1 小时前
围观前后端对接的 TypeScript 最佳实践,我们缺什么?
前端·后端·api
Livingbody3 小时前
大模型微调数据集加载和分析
后端
Livingbody3 小时前
第一次免费使用A800显卡80GB显存微调Ernie大模型
后端
Goboy4 小时前
Java 使用 FileOutputStream 写 Excel 文件不落盘?
后端·面试·架构
Goboy4 小时前
讲了八百遍,你还是没有理解CAS
后端·面试·架构
麦兜*5 小时前
大模型时代,Transformer 架构中的核心注意力机制算法详解与优化实践
jvm·后端·深度学习·算法·spring·spring cloud·transformer
树獭叔叔5 小时前
Python 多进程与多线程:深入理解与实践指南
后端·python
阿华的代码王国5 小时前
【Android】PopupWindow实现长按菜单
android·xml·java·前端·后端