当前位置: 首页 > news >正文

springCloud二-SkyWalking3-性能剖析-⽇志上传-告警管理-接入飞书

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 1. 性能剖析
  • 2. ⽇志上传
    • 2.1 ⽇志配置
  • 3. 告警管理
    • 3.1 告警规则
    • 3.2 Webhook
      • 3.2.1 SkyWalking 的 WebHook 实现
        • 3.2.1.1 告警触发与推送
        • 3.2.1.2 WebHook配置
        • 3.2.1.3 典型应⽤场景
      • 3.2.2 WebHook实践
        • 3.2.2.1 配置WebHook
        • 3.2.2.2 接⼝开发
      • 3.2.3 配置126网易邮件告警
  • 3.3 接入飞书
  • 总结


前言

1. 性能剖析

性能剖析功能是⼀种针对分布式系统代码级性能的动态分析技术, SkyWalking 提供了追踪分析的功能,可以查看请求调⽤链中具体⽅法或者代码块的执⾏耗时, ⽤于快速识别⾼耗时⽅法(如慢SQL查询等), 定位服务调⽤链(Trace)中具体 Span(单个操作节点)的性能问题

就是分析每一行代码的消耗时间

在这里插入图片描述
点击trace profing
点击新建任务
在这里插入图片描述
选择query9
在这里插入图片描述
点击新建任务

在这里插入图片描述
发现第一行耗时最长
点击这一行,然后点击分析

在这里插入图片描述
在这里插入图片描述

我们找到这里,说明是这个执行了2000ms
在这里插入图片描述
还知道是35行代码耗时
com.bite.order.controller.OrderController.queryOrder:35

在这里插入图片描述

果然是35行

这样我们就知道是哪里代码慢了

2. ⽇志上传

SkyWalking不仅⽀持链路追踪, 还可以集成⽇志数据, 帮助⽤⼾在⼀个平台上统⼀查看⽇志和追踪信息, 基于 Trace ID 实现⽇志与请求链路的⾃动关联,快速定位故障上下⽂.

    public OrderInfo queryOrder(Integer orderId) {log.info("queryOrder,orderId:{}",orderId);return orderMapper.selectById(orderId);}

问题是什么呢,问题就是如果是多线程的话,打印日志的顺序就可能不是按照一个线程打印一堆了,而是按照一种日志打印一堆—》比较混乱

在这里插入图片描述
我们只需要在trace这里点击查看日志

就是把控制台的日志上传到SkyWalking中

配置参考

        <dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>9.4.0</version></dependency>

2.1 ⽇志配置

在这里插入图片描述
我们现在的id与traceId无关,没有关联起来

在这里插入图片描述
但是SkyWalking是有traceId的

所以要配置TraceId,还有上报到SkyWalking中

添加 logback-spring.xml ⽂件
• Logback 框架默认加载的配置⽂件名为 logback.xml , 该名称适⽤于⾮ Spring Boot 应⽤.
• Spring Boot默认会识别logback-spring.xml, 这是Spring Boot推荐的⽅式, 优先级⾼于默认logback.xml, ⽀持 Spring 扩展特性(如 ${spring.profiles.active})
• 若同时存在 logback.xml 和 logback-spring.xml , Spring Boot 优先加载 logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"></configuration>

大框架

在日志中打印traceId
set %tid in Pattern section of logback.xml

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender>

appender 是负责日志的输出的核心组件,把日志内容输出到指定的目标

ConsoleAppender表示输出到控制台
Pattern表示输出的格式
其中%tid就是traceId

        <root level="INFO"><appender-ref ref="STDOUT"/></root>

这个是定义STDOUT日志输出的级别

在这里插入图片描述

在这里插入图片描述
这个TID就是traceID

然后是日志上报到SkyWalking中

grpc上报日志到SkyWalking中

    <appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender>

GRPCLogClientAppender就是上报日志到SkyWalking

    <root level="INFO"><appender-ref ref="STDOUT"/><appender-ref ref="grpc-log"/></root>

这样就可以了

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><root level="INFO"><appender-ref ref="STDOUT"/><appender-ref ref="grpc-log"/></root></configuration>

这是总体代码
在这里插入图片描述
这样日志就来了

而且它把每一个trace的日志都是放在一起的

在这里插入图片描述
这些上传的日志都是由于trace引起的日志,有traceId才行
启动的时候的日志就不会上传了

3. 告警管理

除了指标的监测之外, SkyWalking 还提供了告警功能. 当系统出现异常时(如接⼝响应慢, 成功率低), ⾃动触发通知, 帮助研发⼈员或者运维⼈员快速定位问题

在这里插入图片描述
点击告警
在这里插入图片描述
点击进入有告警详情

希望配置告警,比如成功率低于80%的时候告警
还有就是告警希望可以通过邮件等形式告诉我,不然我不可能一直盯着页面看吧

3.1 告警规则

SkyWalking 的告警系统预先定义了⼀部分告警规则, 在 config/alarm-settings.yml ⽂件中, ⽤⼾也可以⾃定义告警规则.

在这里插入图片描述

告警规则

默认告警规则

为⽅便起⻅,SkyWalking提供了⼀个默认的alarm-setting.yml, 包括以下规则:

  1. 过去 3 分钟内服务平均响应时间超过 1 秒。
  2. 最近 2 分钟服务成功率低于 80%。
  3. 过去 3 分钟内超过 1 秒的服务响应时间百分位数
  4. 服务实例在过去 2 分钟内的平均响应时间超过 1 秒,并且实例名称与正则表达式匹配。
  5. 终端节点在过去 2 分钟内的平均响应时间超过 1 秒。
  6. 过去 2 分钟内数据库访问平均响应时间超过 1 秒。
  7. 终端节点关系 过去 2 分钟内超过 1 秒的平均响应时间。

在这里插入图片描述
service_resp_time_rule是告警的规则名称
规则名称必须是唯一的,而且必须以_rule结尾

expression是告警规则的配置

sum(service_resp_time > 1000) >= 3的意思就是一分钟内(一分钟统计)有三次响应时间大于一秒钟------》告警

period:10表示统计最近十分钟内的

    silence-period: 5

这个表示静默时长,报警之后5分钟之内,就不报警了

message表示告警的信息

XXXX_rule: 规则名称, 必须以"_rule" 结尾
• expression:告警表达式, 结果为1, 触发报警
• period: 告警周期, 评估指标的时间⻓度(以分钟为单位)
• silence-period: 静默期, 在告警触发后, 多⻓时间内不再触发.Time-N (TN)触发告警后,在"TN -> TN +period"时间段内保持静默.默认情况下, 它的⼯作⽅式与period相同. 同⼀告警在⼀个周期内只能触发⼀次
• message: 告警消息

所以service_resp_time_rule就是过去 3 分钟内服务平均响应时间超过 1 秒。

database_access_resp_time_rule:过去 2 分钟内数据库访问平均响应时间超过 1 秒。

endpoint_relation_resp_time_rule:终端节点关系 过去 2 分钟内超过 1 秒的平均响应时间。等等
rules:下面的_rule都是SkyWalking默认支持的告警—》都是会生效的
当然你也可以在alarm-settings.yml这个文件中自己配置规则

#hooks:
#  webhook:
#    default:
#      is-default: true
#      urls:
#        - http://127.0.0.1/notify/
#        - http://127.0.0.1/go-wechat/

这个配置呢
默认告警会显示在SkyWalking的UI界面上

webhook就是主动通知我们告警信息的,而不是让我们自己去ui界面查看

3.2 Webhook

webhook是⼀种允许应⽤程序向外部系统(飞书,微信)实时推送事件或数据的机制, 通常通过HTTP回调实现, 从⽽实现跨系统⾃动化的信息传递

核⼼特征:
• 事件驱动: 当预设条件触发时(如告警触发、数据更新), 主动向⽬标 URL 发送 HTTP 请求(通常为POST)
• 轻量级集成: 接收⽅只需提供⼀个可访问的 HTTP 端点即可接收数据, ⽆需轮询查询
• 灵活扩展: 适⽤于告警通知, 流程触发, 数据同步等场景

3.2.1 SkyWalking 的 WebHook 实现

SkyWalking 提供了WebHook的⽅式, 主要⽤于告警通知

3.2.1.1 告警触发与推送

当监控指标(如响应时间、错误率等)达到告警规则阈值时, SkyWalking会⽣成告警事件, ⾃动把告警信息封装为JSON格式, 通过HTTP的⽅式发送⾄预设的WebHook接收地址.

#hooks:
#  webhook:
#    default:
#      is-default: true
#      urls:
#        - http://127.0.0.1/notify/
#        - http://127.0.0.1/go-wechat/

http的url就是在这里配置的

告警json格式

在这里插入图片描述
我们去查看一下这个文件List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>

在这里插入图片描述
点这个

在这里插入图片描述

点击star
跳转到github
然后搜索AlarmMessage

在这里插入图片描述

就是这个类,就是告警信息

scopeId、scope: 告警⽬标的监控范围, 参考org.apache.skywalking.oap.server.core.source.DefaultScopeDefine 中定义

DefaultScopeDefine 也可以搜索到

在这里插入图片描述
◦ scopeId、scope:就是说你是端点告警还是service告警还是实例告警

Name: 告警⽬标的名称,如服务名、端点名等

在这里插入图片描述
就这几个告警

id0: ⽬标实体的主要ID,通常是数据库中的主键
◦ id1: ⽬标实体的次要ID(可选),⽤于更精确的标识

ruleName: 触发告警的规则名称—》alarm-settings.yml中的
◦ alarmMessage: 具体的告警消息内容
◦ startTime: 告警触发的时间戳(毫秒)
◦ 标签: 标签列表,包含与告警相关的附加信息

3.2.1.2 WebHook配置

在 alarm-settings.yml 中定义 WebHook 地址及关联规则

hooks:webhook:default:is-default: trueurls:- http://127.0.0.1/notify/- http://127.0.0.1/go-wechat/

urls 为接收告警的HTTP端点

3.2.1.3 典型应⽤场景

◦ 集成第三⽅系统: 推送告警⾄钉钉, 企业微信、⻜书, 邮箱等协作⼯具.
◦ ⾃动化运维: 触发运维脚本(如⾃动扩容)或联动故障管理系统.
◦ 数据聚合分析: 将告警事件转发⾄⼤数据平台进⾏统计分析

3.2.2 WebHook实践

3.2.2.1 配置WebHook

配置 alarm-settings.yml , 然后重启

我们再来创建一个专门用于告警的应用程序

hooks:webhook:default:is-default: trueurls:- http://127.0.0.1:8084/alarm/handler
3.2.2.2 接⼝开发

在这里插入图片描述

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin></plugins></build>
server:port: 8084
logging:pattern:dateformat: HH:mm:ss:SSS
@RestController
@RequestMapping("/alarm")
public class AlarmController {@RequestMapping("/handler")public String handler(){}
}
@Setter
@Getter
public class AlarmMessage {private int scopeId;private String scope;private String name;private String id0;private String id1;private String ruleName;private String alarmMessage;private List<Tag> tags;private long startTime;private transient int period;private Set<String> hooks = new HashSet<>();private String expression;private JsonObject mqeMetricsSnapshot;
}

给我们的告警信息是一个AlarmMessage 的json格式
所以这个类也要创建

@Setter
@Getter
public class AlarmMessage {private int scopeId;private String scope;private String name;private String id0;private String id1;private String ruleName;private String alarmMessage;private List<Tag> tags;private long startTime;private transient int period;private String expression;
}

我们创建的删除了一些属性
在这里插入图片描述
说错了,这个才是给我们的json里面的内容
所以要含有tags,全部属性都要含有
在这里插入图片描述

这个Tag怎么处理呢

搜索Tag.java

在这里插入图片描述
还是仿照官方的

@Data
public class AlarmMessage {private int scopeId;private String scope;private String name;private String id0;private String id1;private String ruleName;private String alarmMessage;private List<Tag> tags;private long startTime;private transient int period;private String expression;@Datapublic class Tag {private String key;private String value;}
}

这样就OK了

@Slf4j
@RestController
@RequestMapping("/alarm")
public class AlarmController {@RequestMapping("/handler")public String handler(@RequestBody AlarmMessage alarmMessage){log.info("接收到告警,alarmMessage:{}",alarmMessage);return "接收到告警"; }
}

然后SkyWalking也要重启
然后jmeter跑起来

在这里插入图片描述
我们等待UI界面,直到UI界面出现最新的告警信息—》只要第一个出来了,后面就很快了

这个17:21的是十几分钟以前的

在这里插入图片描述
OK,新的告警信息来了
在这里插入图片描述
我们看到error了,说json解析异常

在这里插入图片描述
他说接收到的json是一个数组

    @RequestMapping("/handler")public String handler(@RequestBody List<AlarmMessage> alarmMessageList){log.info("接收到告警,alarmMessageList:{}",alarmMessageList);return "接收到告警";}

在这里插入图片描述
新告警又来了

在这里插入图片描述
也是打印出来了

3.2.3 配置126网易邮件告警

SkyWalking的WebHook功能, 会通过HTTP的⽅式, 把告警信息发送⾄预设的WebHook接收地址, 我们可以借此功能在这个接⼝⾥实现发送邮件或者短信等功能, 从⽽达到告警主动通知.

springboot发送邮件

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
spring:mail:# 指定邮件服务器地址host: smtp.qq.com

这个是qq邮箱

spring:mail:# 指定邮件服务器地址host: smtp.126.com

这个是126邮箱

手机下载网易邮箱,注册网易免费邮箱一个就可以了

spring:mail:# 指定邮件服务器地址host: smtp.126.com

网易邮箱

然后是申请授权码了

在这里插入图片描述

设置–》点击pop3

在这里插入图片描述

然后我们开启pop3/SMTP

这样就会出现了

spring:mail:# 指定邮件服务器地址host: smtp.126.com# 登录账户username: xxxxx@126.com# 授权码password: "xxxxxxxx"# 端口port: 465# 默认编码default-encoding: UTF-8# 使用的协议protocol: smtps# 其他的属性properties:"mail.smtp.connectiontimeout": 5000"mail.smtp.timeout": 3000"mail.smtp.writetimeout": 5000"mail.smtp.auth": true"mail.smtp.starttls.enable": true"mail.smtp.starttls.required": true

只需要改账户名授权码和host就可以了

在这里插入图片描述
这里有测试代码,我们直接复制就可以了

@SpringBootTest
class AlarmServiceApplicationTest {@AutowiredJavaMailSender javaMailSender;@Testvoid sendEmail() throws Exception{// 创建一个邮件消息MimeMessage message = javaMailSender.createMimeMessage();// 创建 MimeMessageHelperMimeMessageHelper helper = new MimeMessageHelper(message, false);// 发件人邮箱和名称helper.setFrom("ck_yyds@126.com", "springdoc");// 收件人邮箱helper.setTo("ck_yyds@126.com");// 邮件标题helper.setSubject("Hello");// 邮件正文,第二个参数表示是否是HTML正文helper.setText("Hello <strong> World</strong>!", true);// 发送javaMailSender.send(message);}}

在这里插入图片描述

这样就成功了

我们分装一下发送邮件的方法

    @Autowiredprivate MailProperties mailProperties;

我们注入这个

在这里插入图片描述
这个类MailProperties 会读取邮件的配置信息

在这里插入图片描述

这些都是默认的配置可以不写

spring:mail:# 其他的属性properties:"personal": "ck告警系统" #发送人姓名"subject": "告警通知"#邮件标题

我们设置这个

@Slf4j
@Configuration
public class Mail {@Autowiredprivate JavaMailSender javaMailSender;@Autowiredprivate MailProperties mailProperties;public void sendEmail(String to,String content)  {try {// 创建一个邮件消息MimeMessage message = javaMailSender.createMimeMessage();// 创建 MimeMessageHelperMimeMessageHelper helper = new MimeMessageHelper(message, false);String from = mailProperties.getUsername();// 发件人邮箱和名称helper.setFrom(from, mailProperties.getProperties().getOrDefault("personal",from));//如果没有获取到personal的值,就是用默认值from// 收件人邮箱helper.setTo(to);// 邮件标题helper.setSubject(mailProperties.getProperties().getOrDefault("subject","告警通知"));// 邮件正文,第二个参数表示是否是HTML正文helper.setText(content, true);// 发送javaMailSender.send(message);}catch (Exception e){log.error("邮件发送失败,e:{}",e);}}
}

这样就分装好了

    @Autowiredprivate Mail mail;
    @RequestMapping("/handler")public String handler(@RequestBody List<AlarmMessage> alarmMessageList){log.info("接收到告警,alarmMessageList:{}",alarmMessageList);mail.sendEmail("ck_yyds@126.com",buildContent(alarmMessageList));return "接收到告警";}private String buildContent(List<AlarmMessage> alarmMessageList) {StringBuilder builder = new StringBuilder();builder.append("告警详情:");for (AlarmMessage message:alarmMessageList){builder.append("<br/>scopeId:").append(message.getScopeId()).append("<br/>scope:").append(message.getScope()).append("<br/>Name:").append(message.getName()).append("<br/>Id0:").append(message.getId0()).append("<br/>RuleName:").append(message.getRuleName()).append("<br/>AlarmMessage:").append(message.getAlarmMessage()).append("<br/>StartTime:").append(message.getStartTime()).append("<br/>-------------------------");}return builder.toString();}

然后启动等待告警
在这里插入图片描述
在这里插入图片描述

3.3 接入飞书

SkyWalking的WebHook功能, 也集成了第三⽅系统, 可以通过简单的配置, 推送告警⾄Slack, 企业微信, 钉钉, ⻜书等.

接入飞书
钉钉和飞书是一样的
微信只支持企业微信

钉钉

  1. 先注册飞书账号
  2. 创建机器⼈
    打开⻜书群组 → 点击右上⻆「设置」→「群机器⼈」→「添加机器⼈」→ 选择「⾃定义机器⼈」
    配置机器⼈名称, 获取⽣成的 Webhook URL(格式为 https://open.feishu.cn/openapis/bot/v2/hook/xxxxxx )

在这里插入图片描述
随便找一个群,点击设置
里面有一个群机器人
点击添加机器人
在这里插入图片描述

选择自定义机器人
在这里插入图片描述
成功之后会有一个webhook的地址–》记录下来

在这里插入图片描述
设置这个的话,发送请求就必须要有签名校验了

在这里插入图片描述

直接复制这个配置就可以了
但是还要加上第一级:hooks

hooks:feishu:default:is-default: truetext-template: |-{"msg_type": "text","content": {"text": "Apache SkyWalking Alarm: \n %s."},"ats":"feishu_user_id_1,feishu_user_id_2"}      webhooks:- url: https://open.feishu.cn/open-apis/bot/v2/hook/dummy_tokensecret: dummysecret

ats这个是配置具体的userId,就是通知指定的一个人

这里的url改为刚刚添加机器人的webhook地址
secret就改为刚刚的签名
没有设置签名校验的话,secret就不用配置

然后就是重启SkyWalking

初始化慢慢等待吧

在这里插入图片描述
在这里插入图片描述
新告警来了,飞书也来消息了

如果想使用更加个性化的模版的话,SkyWalking就不行了

在这里插入图片描述
可以点击这个链接

在群组中使用机器人

总结

http://www.dtcms.com/a/560679.html

相关文章:

  • 【项目基础】vue-class-component、vue-property-decorator、vuex-class、GeoJson
  • JWT 是由哪三个部分组成?如何使用JWT进行身份认证?
  • 【JUnit实战3_24】 第十四章:JUnit 5 扩展模型(Extension API)实战(下)
  • PostgreSQL pg_stat_bgwriter 视图各个字段详解
  • 简单的购物网站设计网页设计尺寸pc端
  • Unity 高效 ListView GridView
  • 【3DV 进阶-4】VecSet 论文+代码对照理解
  • Oracle实用参考(13)——Oracle for Linux (RAC)到Oracle for Linux(单实例)间OGG单向复制环境搭建(2)
  • 前端开发 网站建设头像logo图片在线制作免费
  • 电话语音接入扣子介绍
  • Go分布式追踪实战:从理论到OpenTelemetry集成|Go语言进阶(15)
  • Vue-理解 vuex
  • 【Android】View滑动的实现
  • 广西南宁网站优化急切网头像在线制作图片
  • 创建对象中的单例模式
  • AI革新汽车安全软件开发
  • 单例模式并使用多线程方式验证
  • 小梦音乐下载器(高品质MP3下载) 中文绿色版
  • 网站群发推广软件wordpress页面显示文章
  • Redis大Key调优指针
  • Redis BigKey场景实战
  • Vue消息订阅与发布
  • 12306网站建设超30亿个人网站做贷款广告
  • 《Streamlit 交互式 Web 应用开发》总结测试题
  • 大连 网站制作黑龙江做网站
  • ASP.NET Core 9 Web Api 启用 Swagger
  • Web APIs学习第三天:事件
  • UVa 1597 Searching the Web
  • 5分钟读懂MySQL+Redis双写一致性实现流程
  • 从零开始构建PDF文档生成器(二)- 添加页眉页脚