python微服务监控_SkyWalking - 实现微服务监控告警

关于SkyWalking的基础使用参考:

官方文档:

SkyWalking 告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中。 告警规则的定义分为两部分:

告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。

Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知

告警规则

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

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

服务成功率在过去2分钟内低于80%

服务90%响应时间在过去3分钟内低于1000毫秒

服务实例在过去2分钟内的平均响应时间超过1秒

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

这些预定义的告警规则,打开config/alarm-settings.yml文件即可看到。其具体内容如下:

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_p90_sla_rule:

# Metrics value need to be long, double or int

metrics-name: service_p90

op: ">"

threshold: 1000

period: 10

count: 3

silence-period: 5

message: 90% response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes

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

除此之外,官方还提供了一个config/alarm-settings-sample.yml文件,该文件是一个告警规则的示例文件,里面展示了目前支持的所有告警规则配置项:

# Sample alarm rules.

rules:

# Rule unique name, must be ended with `_rule`.

endpoint_percent_rule:

# Metrics value need to be long, double or int

metrics-name: endpoint_percent

threshold: 75

op: <

# The length of time to evaluate the metrics

period: 10

# How many times after the metrics match the condition, will trigger alarm

count: 3

# How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.

silence-period: 10

message: Successful rate of endpoint {name} is lower than 75%

service_percent_rule:

metrics-name: service_percent

# [Optional] Default, match all services in this metrics

include-names:

- service_a

- service_b

exclude-names:

- service_c

threshold: 85

op: <

period: 10

count: 4

告警规则配置项的说明:

Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义

Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script

Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)

Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空)

Threshold:阈值

OP: 操作符,目前支持 >、<、=

Period:多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配

Count:在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报

Silence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次

message:告警消息

Webhook(网络钩子)

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

SkyWalking的告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,其JSON 数据实基于List

[{

"scopeId": 1,

"scope": "SERVICE",

"name": "serviceA",

"id0": 12,

"id1": 0,

"ruleName": "service_resp_time_rule",

"alarmMessage": "alarmMessage xxxx",

"startTime": 1560524171000

}, {

"scopeId": 1,

"scope": "SERVICE",

"name": "serviceB",

"id0": 23,

"id1": 0,

"ruleName": "service_resp_time_rule",

"alarmMessage": "alarmMessage yyy",

"startTime": 1560524171000

}]

字段说明:

scopeId、scope:所有可用的 Scope 详见 org.apache.skywalking.oap.server.core.source.DefaultScopeDefine

name:目标 Scope 的实体名称

id0:Scope 实体的 ID

id1:保留字段,目前暂未使用

ruleName:告警规则名称

alarmMessage:告警消息内容

startTime:告警时间,格式为时间戳

邮件告警功能实践

根据以上两个小节的介绍,可以得知:SkyWalking是不支持直接向邮箱、短信等服务发送告警信息的,SkyWalking只会在发生告警时将告警信息发送至配置好的Webhook接口。

但我们总不能人工盯着该接口的日志信息来得知服务是否发生了告警,因此我们需要在该接口里实现发送邮件或短信等功能,从而达到个性化的告警通知。

接下来开始动手实践,这里基于Spring Boot进行实现。首先是添加依赖:

org.springframework.boot

spring-boot-starter-mail

配置邮箱服务:

server:

port: 9134

#邮箱配置

spring:

mail:

host: smtp.163.com

#发送者邮箱账号

username: 你的邮箱@163.com

#发送者密钥

password: 你的邮箱服务密钥

default-encoding: utf-8

port: 465 #端口号465或587

protocol: smtp

properties:

mail:

debug:

false

smtp:

socketFactory:

class: javax.net.ssl.SSLSocketFactory

根据SkyWalking发送的JSON数据定义一个DTO,用于接口接收数据:

@Data

public class SwAlarmDTO {

private Integer scopeId;

private String scope;

private String name;

private Integer id0;

private Integer id1;

private String ruleName;

private String alarmMessage;

private Long startTime;

}

接着定义一个接口,实现接收SkyWalking的告警通知,并将数据发送至邮箱:

package com.example.alarmdemo.controller;

import com.example.alarmdemo.dto.SwAlarmDTO;

import lombok.RequiredArgsConstructor;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.mail.SimpleMailMessage;

import org.springframework.mail.javamail.JavaMailSender;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Slf4j

@RestController

@RequiredArgsConstructor

@RequestMapping("/alarm")

public class SwAlarmController {

private final JavaMailSender sender;

@Value("${spring.mail.username}")

private String from;

/**

* 接收skywalking服务的告警通知并发送至邮箱

*/

@PostMapping("/receive")

public void receive(@RequestBody List alarmList) {

SimpleMailMessage message = new SimpleMailMessage();

// 发送者邮箱

message.setFrom(from);

// 接收者邮箱

message.setTo(from);

// 主题

message.setSubject("告警邮件");

String content = getContent(alarmList);

// 邮件内容

message.setText(content);

sender.send(message);

log.info("告警邮件已发送...");

}

private String getContent(List alarmList) {

StringBuilder sb = new StringBuilder();

for (SwAlarmDTO dto : alarmList) {

sb.append("scopeId: ").append(dto.getScopeId())

.append("\nscope: ").append(dto.getScope())

.append("\n目标 Scope 的实体名称: ").append(dto.getName())

.append("\nScope 实体的 ID: ").append(dto.getId0())

.append("\nid1: ").append(dto.getId1())

.append("\n告警规则名称: ").append(dto.getRuleName())

.append("\n告警消息内容: ").append(dto.getAlarmMessage())

.append("\n告警时间: ").append(dto.getStartTime())

.append("\n\n---------------\n\n");

}

return sb.toString();

}

}

最后将该接口配置到SkyWalking中,Webhook的配置位于config/alarm-settings.yml文件的末尾,格式为http://{ip}:{port}/{uri}。如下示例:

[root@ip-236-048 skywalking]# vim config/alarm-settings.yml

webhooks:

- http://127.0.0.1:9134/alarm/receive

测试告警功能

完成告警接口的开发及配置后,我们来进行一个简单的测试。这里有一条调用链路如下:

5cc42569af6f

image.png

我在/producer接口中增加了一行会导致异常的代码,故意使该接口不可用:

@GetMapping

public String producer() {

log.info("received a request");

int i = 1 / 0;

return "this message from producer";

}

接下来编写一段测试代码,让其服务成功率满足在过去2分钟内低于80%这条默认的告警规则:

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

for (int i = 0; i < 100; i++) {

String result = restTemplate.getForObject("http://127.0.0.1:8936/consumer", String.class);

log.info(result);

}

}

执行完测试代码,等待约两分钟后,告警接口的控制台输出了一段日志信息:

5cc42569af6f

image.png

此时,邮箱正常收到了告警邮件:

5cc42569af6f

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值