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

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

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

周期性波动

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

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

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

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

日同比、周同比、月同比

首先要明白,系统绝大部分时间段都是正常的,只有很少的时间段是异常的。将当前时间和历史上的某一天的同一时间进行对比,能有效发现异常。例如 昨天 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,绘制图表
相关推荐
AskHarries41 分钟前
Java字节码增强库ByteBuddy
java·后端
佳佳_1 小时前
Spring Boot 应用启动时打印配置类信息
spring boot·后端
许野平2 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
BiteCode_咬一口代码3 小时前
信息泄露!默认密码的危害,记一次网络安全研究
后端
齐 飞4 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
LunarCod4 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
码农派大星。5 小时前
Spring Boot 配置文件
java·spring boot·后端
杜杜的man5 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*5 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu5 小时前
Go语言结构体、方法与接口
开发语言·后端·golang