一、布景

转转根据Prometheus落地了一体化监控体系,并自研了告警体系,但研制同学每人每天都会接收到许多告警,导致重要的告警被吞没,部分同学会挑选直接屏蔽掉一切告警,进一步加重问题。告警过多等同于没有告警

别的,多个告警之间一般具有一定的关联性,如:SQL执行过错告警导致异常日志过多告警。而面临杂乱无章的告警,很难快速分析出告警的根本原因。

告警降噪治理十分重要,在此布景下,咱们根据Alertmanager扩展研制了转转告警中心。

二、标准与SDK

2.1 发送告警

Alertmanager供给了告警发送的OpenAPI,其间,告警的labels用于辨认同一条告警并对告警去重、降噪,相同labels的告警的annotations会被覆盖。startsAt与endsAt分别为告警发生时刻与结束时刻。

[
  {
    "labels": {
      "<labelname>": "<labelvalue>",
      ...
    },
    "annotations": {
      "<labelname>": "<labelvalue>",
    },
    "startsAt": "<rfc3339>",
    "endsAt": "<rfc3339>",
    "generatorURL": "<generator_url>"
  },
  ...
]

一条告警从提交到发送再到接收人的流程大致如下图所示,其间,Alertmanager需求集群布置来保证高可用性,需求留意的是,发送告警时不能对集群做负载均衡,必需要对集群内一切的Alertmanager发送告警才能保证高可用性。

基于Alertmanager设计告警降噪系统,成本低可落地

2.2 常用标签

Alertmanager为根据标签的告警降噪,需提前标准告警常见标签。

  • ENV:环境,如:线上环境、测试环境
  • APP:服务名
  • SOURCE:告警来历,如:日志告警、JVM告警
  • NAME:告警称号
  • LEVEL:告警等级,如:P0告警、P5告警
  • INSTANCE:告警实例IP
  • RECEIVER_TYPE:告警接受者类型
  • RECEIVER:告警接受者,与RECEIVER_TYPE配合使用,如RECEIVER_TYPE=邮件,RECEIVER即为邮箱地址。

Alertmanager标签名的正则规则为[a-zA-Z_][a-zA-Z0-9_]*,在真正发送告诉时,最好将标签名做一次中文映射转化。

2.3 SDK

咱们针对Alertmanager开发了发送告警的SDK,如下所示,发送告警非常简单,SDK默许会为每条告警主动增加服务名、环境、IP、告警等级,并依照接收方拆开为多条告警发送。每一项内容都是标签,其间value较为特殊,放在了annotations内,其他均放在了labels内用于唯一辨认一条告警。

AlertManager alertManager = AlertManager.builder()
                //告警称号,必传
                .name("告警Demo")
                //告警标签,拓宽信息,非必传
                .label("label1", "value1")
                .label("label2", "value2")
                //告警值,非必传
                .value("123")
                //指定为企业微信告警,并指定发送人
                .wechat("zhangsan", "lisi")
                .build();
//同步发送告警
alertManager.send();
//异步发送,默许线程
alertManager.sendAsync();
//自界说线程池发送
ThreadPoolExecutor executor;
executor.execute(alertManager);

三、告警降噪

3.1 分组去重

分组机制能够将多条告警信息兼并成一个告诉。例如,当集群中有数百个正在运转的服务实例,假如此刻发生了网络故障,结果就会有数百个告警被发送到Alertmanager。

而作为用户,或许只期望能够在一个告诉中就能检查哪些服务实例受到影响。这时能够依照服务地点集群或者告警称号对告警进行分组,将这些告警聚合在一起成为一个告诉。

Alertmanager能够将收到的告警依照特定的标签分组、去重,并根据以下参数决定何时发送组内的告警告诉,Alertmanager的每一次告诉都会包括当时组内的一切告警。

  • 初始等候时刻(group_wait):一组告警第一次发送之前等候的时刻,用于等候同一组的更多告警兼并发送。
  • 改变等候时刻(group_interval):一组已发送初始告诉的告警在接收到新告警或有告警康复后,再次发送告诉前等候的时刻。
  • 重复等候时刻(repeat_interval):一组已发送初始告诉的告警,组内告警均没有康复且没有新增告警,再次发送告诉前等候的时刻。

下面以一张图,来展现从告警发生到兼并到某个调集中,到发送告诉的整个过程。三角形和圆形表明不断发生的告警,矩形代表实际的告诉时刻以及告警内容。

基于Alertmanager设计告警降噪系统,成本低可落地

3.2 康复告诉

Alertmanager自带康复告诉,默许5m没有收到告警后,告警将被以为康复,然后会等候group_interval后告诉给用户。发送告警时也能够指定告警康复时刻,如下所示:

//告警发生时刻
Date startTime = new Date();
//告警结束时刻,假如在startTime~endTime期间没有告警,则以为告警康复
Date endTime = new Date(new Date().getTime() + 5 * 60 * 1000);
AlertManager.builder().startsAt(startTime).endsAt(endTime)..

需求留意的是,endTime假如小于当时时刻,会以为告警在发出时就已经康复,这条告警不会告诉。

基于Alertmanager设计告警降噪系统,成本低可落地

3.3 告警分级

咱们将告警分为P0~P5六个等级,告警等级默许取决于服务重要性,转转服务依照重要性分了A、B、C、D、E五个等级,服务重要性与告警等级的对应关系:A → P1,B → P2,C → P3,D → P4,E → P5。发送告警时也能够指定告警等级,如下:

AlertManager.builder().level(AlertManager.Level.P0)...

告警分级的目的是尽量让高等级的告警及时发出,低等级的告警减少用户打扰次数。不同等级告警的分组、去重时刻均不相同。

如:P4/P5的告警初始时会等候3m搜集告警,并将当时告警接收者的一切告警汇总到一条告诉内;

P0的告警只会等候15s搜集告警,并依照告警接收者、环境、服务名、告警来历、告警称号为维度拆分红多个告诉。

route:
  group_by: ['...']
  receiver: 'web.hook'
  routes:
  - group_by: ['_RECEIVER', '_RECEIVER_TYPE']
    group_wait: 3m
    group_interval: 10m
    repeat_interval: 4h
    matchers:
     - _LEVEL =~ "P4|P5"
    continue: false
  - group_by: ['_RECEIVER', '_RECEIVER_TYPE', '_ENV']
    group_wait: 2m
    group_interval: 10m
    repeat_interval: 2h
    matchers:
     - _LEVEL = "P3"
    continue: false
  # ... 省略P3、P2、P1、P0降噪战略
告警等级 分组标签 group_wait group_interval repeat_interval
P0 告警接收者、环境、服务名、告警来历、告警称号 15s 1m 30m
P1 告警接收者、环境、服务名、告警来历 30s 5m 1h
P2 告警接收者、环境、服务名 1m 5m 1h
P3 告警接收者、环境 2m 10m 2h
P4/P5 告警接收者 3m 10m 4h

3.4 告诉兼并

统一使用Alertmanager webhook告诉,一次告诉内容会包括分组内的多个报警,咱们会依照告警类似度对告警做兼并,如下为6条报警兼并成一条告诉,其间,告警值与服务实例一一对应。

基于Alertmanager设计告警降噪系统,成本低可落地

界说类似度:关于多个报警的labels,只要一个label value不一样,剩下的label key与label value均相同,则以为类似并兼并;一次Alertmanager webhook告诉可依照类似度拆分红多种告警,不同的告警提取公共标签,终究推送到一条告诉内。

如下,为4条告警兼并到一条告诉,可清晰的看到两台机器的异常日志报警的原因是因为Druid执行SQL过错导致。

基于Alertmanager设计告警降噪系统,成本低可落地

3.5 告警按捺

按捺是指当某一告警发出后,能够停止重复发送由此告警引发的其它告警的机制。

当同一个服务、环境、告警来历、IP、接受者、告警称号,一起呈现多个等级的告警时,高等级的告警会按捺低等级告警的告诉。

如:告警称号为FGC次数,P1告警阈值为20次,P2告警为10次,当某个实例的FGC次数到达20次以上时,只会发送P1告警,不会发送P2告警。

inhibit_rules:
 - source_matchers:
    - _LEVEL="P4"
   target_matchers:
    - _LEVEL="P5"
   equal: ['_APP', '_ENV', '_SOURCE', '_INSTANCE', '_RECEIVER', '_RECEIVER_TYPE', '_NAME']
 - source_matchers:
    - _LEVEL="P3"
   target_matchers:
    - _LEVEL=~"P4|P5"
   equal: ['_APP', '_ENV', '_SOURCE', '_INSTANCE', '_RECEIVER', '_RECEIVER_TYPE', '_NAME']
 # ... 省略P2、P1、P0按捺战略

四、多告诉机制

支撑企业微信、企业微信群、短信、邮件、电话、WebHook,可在一个告警内一起指定多种接收方式,咱们会主动依照接收人拆分红多条告警。

  • 企业微信、企业微信群、邮件、WebHook:最具体,发送告警与康复告诉。
  • 短信:相对以上,只是不会发送康复告诉。
  • 电话:不会发送康复告诉,而且只会播报报警标题与告警服务名。
AlertManager.builder()
            //企业微信
            .wechat("zhangsan","lisi")
            //指定了消息通道的企业微信
            .wechat(Arrays.asList("zhangsan","lisi"), "10")
            //企业微信群聊机器人
            .wechatRobot("企业微信群机器人key")
            //邮件
            .mail("zhangsan@zhuanzhuan.com", "lisi@zhuanzhuan.com")
            //Http回调
            .webhook("http://www.baidu.com")
            //短信
            .sms("188xxxxxxxx", "180xxxxxxxx")
            //语音电话
            .phone("188xxxxxxxx", "180xxxxxxxx")..

五、未康复告警

为了防止告警过多时吞没了重要告警,在每条告警的最终,都供给了一个未康复告警链接,用于实时查询当时未康复的告警。

未康复告警具有三种状况:活泼、静默、按捺。其间,活泼状况能够设置静默,静默状况能够检查被谁静默。

基于Alertmanager设计告警降噪系统,成本低可落地

六、静默告警

根据Alertmanager OpenAPI,支撑根据标签的静默告警,每条告警告诉内都供给了一个链接用于快速静默,也能够在未康复告警内静默告警。

点击新增静默后,会主动补充静默匹配的标签项,也能够增减标签项,如:去掉INSTANCE标签维度以便匹配一切的机器,修正_RECEIVER为其他人等。需求留意的是,增加静默时RECEIVER必需要指定。

增加完成后,会主动跳转到静默列表,并展现刚刚增加的静默项。

基于Alertmanager设计告警降噪系统,成本低可落地

在静默列表内可查询一切的活泼、过期的静默项,可编辑、删除、检查影响的告警。

基于Alertmanager设计告警降噪系统,成本低可落地

检查受影响的告警为实时查询,假如当时静默没有匹配到任何告警,查询结果会为空。

基于Alertmanager设计告警降噪系统,成本低可落地

七、告警前史

告警告诉给用户后,咱们会保存三个月的前史告警记载列表。

基于Alertmanager设计告警降噪系统,成本低可落地

八、总结

Alertmanager供给了告警降噪的战略,咱们在Alertmanager的基础上制定了标签标准、告警分级降噪、分级按捺、告警兼并,并根据Alertmanager OpenAPI扩展了未康复告警、静默告警、告警前史。Alertmanager尽管不是告警降噪的银弹,但也能够处理大部分问题,假如你也面临着告警轰炸的问题,能够测验一下。


关于作者

苑冲,转转架构部存储服务负责人,主要负责MQ、监控体系、Redis、KV存储等。爱学习,喜爱以辩证思想与改变思想思考。

转转研制中心及业界小伙伴们的技能学习沟通平台,定时共享一线的实战经验及业界前沿的技能论题。 关注公众号「转转技能」(综合性)、「大转转FE」(专心于FE)、「转转QA」(专心于QA),更多干货实践,欢迎沟通共享~