【微服务】skywalking自定义告警规则使用详解

目录

一、前言

二、SkyWalking告警功能介绍

[2.1 SkyWalking告警是什么](#2.1 SkyWalking告警是什么)

[2.2 为什么需要SkyWalking告警功能](#2.2 为什么需要SkyWalking告警功能)

[2.2.1 及时发现系统异常](#2.2.1 及时发现系统异常)

[2.2.2 保障和提升系统稳定性](#2.2.2 保障和提升系统稳定性)

[2.2.3 避免数据丢失](#2.2.3 避免数据丢失)

[2.2.4 提高故障处理效率](#2.2.4 提高故障处理效率)

[三、 SkyWalking告警规则](#三、 SkyWalking告警规则)

[3.1 SkyWalking告警规则配置](#3.1 SkyWalking告警规则配置)

[3.2 SkyWalking告警规则参数配置说明](#3.2 SkyWalking告警规则参数配置说明)

[3.3 Webhook介绍](#3.3 Webhook介绍)

[3.3.1 什么是Webhook](#3.3.1 什么是Webhook)

[3.3.2 Webhook 参数说明](#3.3.2 Webhook 参数说明)

[3.3.3 常用的Webhook](#3.3.3 常用的Webhook)

[四、 告警配置之Webhook使用](#四、 告警配置之Webhook使用)

[4.1 操作步骤](#4.1 操作步骤)

[4.1.1 添加依赖](#4.1.1 添加依赖)

[4.1.2 添加一个接口](#4.1.2 添加一个接口)

[4.1.3 打包部署服务器](#4.1.3 打包部署服务器)

[4.2 配置Webhook](#4.2 配置Webhook)

[4.3 触发回调接口](#4.3 触发回调接口)

[4.3.1 告警信息展示](#4.3.1 告警信息展示)

五、告警通知接入钉钉

[5.1 设置钉钉机器人](#5.1 设置钉钉机器人)

[5.2 告警规则配置钉钉机器人](#5.2 告警规则配置钉钉机器人)

[5.3 效果测试验证](#5.3 效果测试验证)

[5.4 告警通知注意事项](#5.4 告警通知注意事项)

[5.4.1 合理设置告警规则](#5.4.1 合理设置告警规则)

[5.4.2 配置合理的告警通知方式和接收人员](#5.4.2 配置合理的告警通知方式和接收人员)

[5.4.3 定期检查和更新配置](#5.4.3 定期检查和更新配置)

六、写在文末


一、前言

在大型分布式系统中,如何在系统中某个服务出问题时能得到快速通知和处理呢,比较常见的做法就是接入告警通知。在分布式系统接入链路追踪、链路可视化大屏等之后,接下来就要考虑如何对系统中的异常情况进行监控告警。

在之前的分享中我们相信介绍了SkyWalking的使用,SkyWalking作为一款开源分布式系统性能监控工具、分布式服务链路追踪工具,不仅提供了很好的链路追踪可视化展示入口,也提供了丰富的告警功能,可以帮助开发或运维人员及时发现系统中的异常情况,从而使问题得到快速的响应与处理。

二、SkyWalking告警功能介绍

2.1 SkyWalking告警是什么

SkyWalking除了提供实时的系统监控、链路追踪与分析功能外,还提供了告警功能,用于监控系统的指标数据,并在系统服务中被监控的指标超过预设阈值时触发告警。如下图,在UI界面上,左侧有一个告警的菜单项,当接入并配置了告警规则后将会看到相关的信息。

2.2 为什么需要SkyWalking告警功能

2.2.1 及时发现系统异常

在分布式系统中,尤其是随着微服务规模越来越大,发生异常情况在所难免,比如服务A调用服务B超时,服务A内部连接mysql超时等等。在SkyWalking中,通过设置告警规则和触发阈值,可以及时监控系统指标数据,并在数据超过预设阈值时触发告警,可以帮助开发和运维人员及时发现系统中的异常情况,让问题得到尽快的处理从而避免问题的进一步扩大。

2.2.2 保障和提升系统稳定性

通过接入告警功能,可以监控系统关键指标,并在指标超过预设阈值时触发告警。通过一段时间或周期性的运行,可帮助团队及时发现系统中潜在的性能问题,并采取相应的措施,从而提升系统的性能和稳定性。

2.2.3 避免数据丢失

在分布式系统中,数据完整性与可靠性是非常重要的。通过设置告警规则和阈值,可以监控系统中服务的关键指标的数据状态,并在数据发送异常时触发告警,从而及时发现数据丢失或损坏的情况,并及时采取相应的措施,避免数据的进一步损失。

2.2.4 提高故障处理效率

当系统出现异常时,如何快速得到通知并及时处理问题是非常重要的。通过接入告警功能,可以将告警的信息及时通知到相关人员,帮助团队人员快速定位和解决问题,从而提高故障处理的效率,减少系统停机时间。

三、 SkyWalking告警规则

3.1 SkyWalking告警规则配置

SkyWalking 告警功能是在6.x版本新增的,其告警是由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中,如下在SkyWalking 的config目录中可以找到该配置:

打开配置之后,可以看到提供了多种配置规则的选项,完整的配置如下:

bash 复制代码
# Sample alarm rules.
rules:
  # Rule unique name, must be ended with `_rule`.
  service_resp_time_rule:
    metrics-name: service_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.
  service_sla_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_sla
    op: "<"
    threshold: 8000
    # The length of time to evaluate the metrics
    period: 10
    # How many times after the metrics match the condition, will trigger alarm
    count: 2
    # How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.
    silence-period: 3
    message: Successful rate of service {name} is lower than 80% in 2 minutes of last 10 minutes
  service_resp_time_percentile_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_percentile
    op: ">"
    threshold: 1000,1000,1000,1000,1000
    period: 10
    count: 3
    silence-period: 5
    message: Percentile response time of service {name} alarm in 3 minutes of last 10 minutes, due to more than one condition of p50 > 1000, p75 > 1000, p90 > 1000, p95 > 1000, p99 > 1000
  service_instance_resp_time_rule:
    metrics-name: service_instance_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 2
    silence-period: 5
    message: Response time of service instance {name} is more than 1000ms in 2 minutes of last 10 minutes
  database_access_resp_time_rule:
    metrics-name: database_access_resp_time
    threshold: 1000
    op: ">"
    period: 10
    count: 2
    message: Response time of database access {name} is more than 1000ms in 2 minutes of last 10 minutes
  endpoint_relation_resp_time_rule:
    metrics-name: endpoint_relation_resp_time
    threshold: 1000
    op: ">"
    period: 10
    count: 2
    message: Response time of endpoint relation {name} is more than 1000ms in 2 minutes of last 10 minutes
#  Active endpoint related metrics alarm will cost more memory than service and service instance metrics alarm.
#  Because the number of endpoint is much more than service and instance.
#
#  endpoint_resp_time_rule:
#    metrics-name: endpoint_resp_time
#    op: ">"
#    threshold: 1000
#    period: 10
#    count: 2
#    silence-period: 5
#    message: Response time of endpoint {name} is more than 1000ms in 2 minutes of last 10 minutes

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/

在实际使用中,我们就是围绕这个配置文件进行各类告警规则的配置进行展开,从上述的配置文件;来看,告警规则的定义分为两部分:

  • 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件;
  • Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知;

3.2 SkyWalking告警规则参数配置说明

SkyWalking 的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下:

  1. 过去 3 分钟内服务平均响应时间超过 1 秒;

  2. 过去 2 分钟服务成功率低于80%;

  3. 过去 3 分钟内服务响应时间超过 1s 的百分比;

  4. 服务实例在过去 2 分钟内平均响应时间超过 1s,并且实例名称与正则表达式匹配;

  5. 过去 2 分钟内端点平均响应时间超过 1 秒;

  6. 过去 2 分钟内数据库访问平均响应时间超过 1 秒;

  7. 过去 2 分钟内端点关系平均响应时间超过 1 秒;

这些预定义的告警规则,打开config/alarm-settings.yml文件即可看到,规则配置中的常用配置项参数说明:

  • Rule name:规则名称,也是在告警信息中显示的唯一名称,必须以_rule结尾,前缀可自定义;
  • Metrics name:度量名称,也是OAL脚本中的度量名,目前只支持long、double和int类型;
  • Include names:该规则作用于哪些实体名称,如服务名,终端名(可选,默认为全部);
  • Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空);
  • include-names-regex:提供一个正则表达式来包含实体名称,如果同时设置包含名称列表和包含名称的正则表达式,则两个规则都将生效;
  • exclude-names-regex:提供一个正则表达式来排除实体名称,如果同时设置排除名称列表和排除名称的正则表达式,则两个规则都将生效;
  • include-labels:包含在此规则之内的标签;
  • exclude-labels:排除在此规则以外的标签;
  • include-labels-regex:提供一个正则表达式来包含标签,如果同时设置包含标签列表和包含标签的正则表达式,则两个规则都将生效;
  • exclude-labels-regex:提供一个正则表达式来排除标签,如果同时设置排除标签列表和排除标签的正则表达式,则两个规则都将生效;
  • Threshold:阈值;
  • OP: 操作符,目前支持 >、<、=;
  • Period:多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配;
  • Count:在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报;
  • Silence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次;
  • message:告警消息;

3.3 Webhook介绍

3.3.1 什么是Webhook

Webhook,即钩子,Webhook简单理解来说,即一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件,当该事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。如下,在SkyWalking告警规则配置文件的最后给出了Webhook的配置样例。

3.3.2 Webhook 参数说明

Webhook 要求一个点对点的 Web 容器,告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,JSON 格式包含以下信息:

  • scopeId:目标 Scope 的 ID;

  • name:目标 Scope 的实体名称;

  • id0:Scope 实体的 ID。id1:未使用;

  • ruleName:您在 alarm-settings.yml 中配置的规则名;

  • alarmMessage. 告警消息内容;

  • startTime. 告警时间戳,当前时间与 UTC 1970/1/1 相差的毫秒数;

下面是一个json数据示例:

bash 复制代码
[{
	"scopeId": 1, 
	"scope": "SERVICE",
	"name": "user-service", 
	"id0": "001",  
	"id1": "",  
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "服务【user-service】的平均响应时间在最近10分钟内有2分钟超过1秒",
	"startTime": 1706324413454
}]

3.3.3 常用的Webhook

事实上,SkyWalking支持多种Webhook,官方文档中提供了丰富的告警规则,下面介绍几种常用的几种Webhook选择。

Alerting | Apache SkyWalking

Slack Chat Hook

您需要遵循传入Webhooks入门指南并创建新的Webhooks。如果您按以下方式配置了Slack Incoming Webhooks,则告警消息将按 Content-Type 为 application/json 通过HTTP的 POST 方式发送。

参考如下示例:

bash 复制代码
slackHooks:
  textTemplate: |-
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": ":alarm_clock: *Apache Skywalking Alarm* \n **%s**."
      }
    }
  webhooks:
    - https://hooks.slack.com/services/x/y/z

微信Hook

只有微信的企业版才支持 Webhooks ,如何使用微信的 Webhooks 可参见如何配置群机器人。如果您按以下方式配置了微信的 Webhooks ,则告警消息将按 Content-Type 为 application/json 通过HTTP的 POST 方式发送

参考如下示例:

bash 复制代码
wechatHooks:
  textTemplate: |-
    {
      "msgtype": "text",
      "text": {
        "content": "Apache SkyWalking 告警: \n %s."
      }
    }
  webhooks:
    - https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=dummy_key

钉钉 Hook

您需要遵循自定义机器人开放并创建新的Webhooks。为了安全起见,您可以为Webhook网址配置可选的密钥。如果您按以下方式配置了钉钉的 Webhooks ,则告警消息将按 Content-Type 为 application/json 通过HTTP的 POST 方式发送。

参考如下示例:

bash 复制代码
dingtalkHooks:
  textTemplate: |-
    {
      "msgtype": "text",
      "text": {
        "content": "Apache SkyWalking 告警: \n %s."
      }
    }
  webhooks:
    - url: https://oapi.dingtalk.com/robot/send?access_token=dummy_token
      secret: dummysecret

四、 告警配置之Webhook使用

上面详细介绍了告警规则配置文件和相关参数的使用,接下来先介绍下Webhook的使用流程。整体思路如下:

  • 搭建一个springboot工程;

  • 提供一个用于webhook回调的接口;

  • 部署工程,并在alarm-settings.yml配置接口回调地址;

工程目录如下

4.1 操作步骤

4.1.1 添加依赖

java 复制代码
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>

        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.23</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>hook-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

4.1.2 添加一个接口

自定义一个接口类,提供一个Webhook中配置使用

java 复制代码
@RestController
@RequestMapping("/alert")
@Slf4j
public class AlertController {

    //localhost:8088/alert/notify
    @PostMapping("/notify")
    public void alterNotify(@RequestBody List<AlarmMessage> messages) {
        log.info("【收到告警通知】,告警消息:【{}】", JSON.toJSONString(messages));
    }

    //localhost:8088/alert/test
    @GetMapping("/test")
    public String test(){
        return "test";
    }

}

AlarmMessage消息通知类

java 复制代码
@Data
@ToString
public class AlarmMessage {

    private int scopeId;
    private String name;
    private String id0;
    private String id1;

    private String alarmMessage;
    private long startTime;
    private String ruleName;

}

测试一下接口,确保可以正常调用

4.1.3 打包部署服务器

将工程打包并部署到服务器上,进行启动,确保服务接口可以正常访问,

这里假设你的服务器已经提前做好相关的环境配置,并且开放了相应的防火墙端口

4.2 配置Webhook

将上述的接口地址配置到alarm-settings.yml中

按照这样的规则配置之后,当该配置文件中的任何一种规则阈值被触发,理论上就可以触发接口的回调,从而输出相应的日志信息。

4.3 触发回调接口

对接口进行改造,在调用获取order的接口逻辑中增加一个时间休眠,在远程调用的user逻辑中,也增加一个休眠时间,这样可以放大问题的发生,触发告警规则;

java 复制代码
public Map getById(String id) {
        log.info("[订单服务] 基于 id 查询订单详情:{}", id);

        Map map = new HashMap();

        Order order = new Order();
        order.setOrderId("0002");
        order.setProductId("0001");
        order.setProductName("小米手机");
        map.put("order",order);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            log.error("thread sleep error");
        }
        User user = userFeignService.getById("001");
        map.put("user",user);
        return map;
}

调用的user接口逻辑

java 复制代码
public User getById(String id) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            log.error("thread sleep error");
        }
        log.info("[用户服务] 基于 id 查询用户信息:{}", id);
        String key = "sw:users:" + id;
        Object json = redisTemplate.opsForValue().get(key);
        if (json != null) {
            log.info("[用户服务] redis 中查询到用户信息:key={}, json={}", key, json);
            return JSON.parseObject(json.toString(), User.class);
        }
        User user = userMapper.getById(id);
        if (user != null) {
            log.info("[用户服务] redis 中不存在,从数据库查到数据并缓存:{}", user);
            redisTemplate.opsForValue().set(key, user, 2, TimeUnit.HOURS);
            return user;
        }
        log.warn("[用户服务] 基于 id 查询用户失败,用户不存在:{}", id);
        return null;
}

启动两个服务,然后调用一下接口,由于调用超时,最后接口响应异常,在控制台的日志中也可以看到详细的信息;

4.3.1 告警信息展示

为了让告警的规则被触发从而将信息展示到UI界面,可以在2分钟内多调用几次接口,而后再在控制台的告警一栏,就能看到展示的告警日志信息了,如下,详细展示了异常的详细链路信息。

也可以点击到某个具体的服务节点查看异常详情

通过上面的示例,演示了如何通过配置webhook进行异常告警的详细过程,事实上,在真实的场景下,将日志投射到界面只是一方面,方便运维回溯异常过程,更通用的诉求是,在触发了告警规则之后,能够将告警信息快速通知到相关的人员,比如通过邮件、短信等方式。这就可以在上述的回调接口中增加对接邮件或短信,或其他通知服务即可。

五、告警通知接入钉钉

在实际工作中,钉钉在企业内部使用的非常多,而SkyWalking也正好支持告警通知接入钉钉,通过将告警通知接入钉钉,严格来说接入钉钉群机器人,当告警规则被触发时,群里将会收到消息通知,方便我们快速响应,官方文档 钉钉接入文档

下面来演示告警规则如何接入钉钉机器人。

5.1 设置钉钉机器人

由于钉钉机器人目前只支持群设置,因此需要先创建一个钉钉群,然后找到下面自定义Webhook的位置进行配置。

添加钉钉机器人,如下

安全设置中,勾选加签(拷贝和保存加签后面生成的密钥串,后面配置Webhook时使用)

最后生成机器人(同样拷贝下Webhook的完整地址并保存一下,后面会用到)

5.2 告警规则配置钉钉机器人

拷贝官网提供的配置信息到alarm-settings.yml中,如下:

然后将上一步中的密钥信息和Webhook地址替换到url和secret中即可,注意信息的保密

5.3 效果测试验证

配置完成后,重启SkyWalking服务,然后再次访问一下上面的接口,多访问几次之后,在UI界面上能看到异常的信息

然后在钉钉群里,就能看到相应的通知告警信息了

上面演示了接入钉钉机器人的过程,其他类型的Webhook配置方式流程大致如此,如果有需要可以查阅官网步骤进行操作即可。

5.4 告警通知注意事项

5.4.1 合理设置告警规则

配置告警规则、设置告警阈值时,需根据实际需求合理设置,避免误报或漏报。以下是一些注意事项:

  • **确定监控指标,**在设置告警规则之前,需明确要监控的指标,这些指标应该是对系统性能和稳定性有重要影响的关键指标。比如可以监控系统的响应时间、吞吐量、错误率等;
  • 设置合理的阈值 ,设置告警规则时,需根据系统实际情况设置合理的阈值。阈值应该能够反映系统正常运行的状态,同时也要能够及时发现潜在的问题,过高或过低的阈值都可能导致误报或漏报;
  • 考虑系统负载和峰值情况 ,设置告警规则和阈值时,需考虑系统负载和峰值情况。例如,在系统峰值期间,可能会出现一些短暂的性能下降或错误增加的情况,这些情况不一定需要触发告警;

5.4.2 配置合理的告警通知方式和接收人员

在配置告警通知方式和接收人员时,需要确保正确配置,并且通知能够及时到达,下面是一些注意事项:

  • 在选择告警通知方式时,要根据实际情况进行选择,常用的告警通知方式像邮件、短信、钉钉、飞书等。根据团队的工作习惯和接收方式,选择合适的通知方式;
  • 配置正确的接收人员,在配置告警通知时,需要确保配置接收人员的联系方式准确无误,通知应该发送给能够及时处理问题的人员,避免延误系统异常处理时间;
  • 测试告警通知,在配置完成后,建议进行测试,确保告警通知能够正常发送和接收,可以通过模拟触发告警的方式,验证告警通知的可用性;

5.4.3 定期检查和更新配置

告警规则配置是一个动态过程,随着系统的综合性能越来越好,早期配置的告警规则可能并不能满足当前的状况,因此需要定期检查和更新。以下是一些注意事项:

  • 定期评估告警规则和阈值的有效性,根据系统实际情况逐步调整和优化。随着系统的发展和变化,可能需要更新告警规则和阈值,以适应新的需求和情况;

  • 定期处理告警反馈和建议,根据使用者的反馈和建议进行优化和改进,可以帮助改进告警功能的准确性和可用性;

  • 定期备份告警配置,以防止配置丢失或损坏,备份可以帮助恢复配置,并在需要时进行回滚;

六、写在文末

本文详细介绍了SkyWalking自定义告警规则的详细使用,并结合实际操作完成了对Webhook的配置演示与效果模拟,SkyWalking的告警功能在实际生产运行过程中可以帮助及时发现系统中的异常情况,从而提升系统问题的发现及时率,提升问题的处理效率,从而提高系统的稳定性和可靠性。通过合理的配置告警规则,可以让系统时刻处于我们的掌控之中。本篇到此结束,感谢观看。