分布式链路追踪-SkyWalking
分布式链路追踪-SkyWalking
- 一. 链路追踪介绍
- 1. 什么是链路追踪
- 2.链路追踪的作用
- 二.为什么选择SkyWalking
- 1. ZipKin
- 2.CAT
- 3.SkyWalking
- 4. 特点对⽐
- 三.术语介绍
- 1.APM
- 2. OAP
- 3.Agent
- 4.UI
- 5. Metrics
- 6. Endpoint
- 四.安装部署
- 1. 下载安装SkyWalking
- 1)下载
- 2)解压
- 2. 数据库选型及配置
- 3.修改配置
- 1) 修改端⼝号(按需)
- 2) 创建数据库
- 3) 修改存储后端为MySQL
- 4. 启动SkyWalking
- 五.SkyWalking快速开始
- 1.服务准备
- 2.服务接⼊以order-service为例
- 3.接⼝请求
- 六.UI介绍
- 1.⻚⾯指标介绍
- 2 模拟接⼝
- 3.观察指标
- 1)Service
- 2)服务详情
- 3)Instance
- 4)Endpoint
- 5)Topology
- 6)Trace
- 4. 数据库指标
- 1)指标介绍
- 2)模拟慢SQL
- 七.⾃定义追踪
- 1.添加依赖
- 2.添加注解@Trace
- 3.附加业务信息
- 八.性能剖析
- 1.新建任务
- 2.观察剖析结果
- 九.⽇志上传
- 1.引⼊依赖
- 2.⽇志配置
- 十.告警管理
- 1.告警规则
- 2.Webhook
- 1) SkyWalking的WebHook实现
- 2)WebHook实践
- (1)配置WebHook
- (2)接⼝开发
- 3)配置邮件告警
- 3.接⼊⻜书
一. 链路追踪介绍
在分布式系统中,⼀次请求往往会经过多个服务节点。⽐如⼀次简单的用户下单请求,可能涉及⽹关,商品服务,库存服务,⽀付服务、消息队列等多个环节。
这些服务节点可能是不同团队开发,部署在不同的服务器上,甚⾄可能使⽤不同的编程语⾔编写。在这⼀系列的调⽤中,可能有串⾏的,也有并⾏的。
在分布式系统中,我们可能会遇到⼀些涉及这就涉及到了链路追踪的问题,比如:
- 这个请求经过了哪些服务节点
- 这些服务节点有什么样的依赖关系
- 各个服务接⼝的性能是如何的
- 如何快速的串联整个链路,并定位问题
1. 什么是链路追踪
链路追踪是分布式系统中跟踪请求全流程的技术,通过记录请求在多个服务间的流转路径,耗时,状态等信息,形成完整的调⽤链视图。也就是将⼀次分布式请求的调⽤情况集中进行展示。
其核⼼是通过唯⼀标识( TraceID )串联跨服务的调⽤单元( Span ),并借助上下⽂传递( Context )实现链路连续性。
核心概念
- Trace:代表⼀次完整的请求处理过程,从请求到响应结束。由多个 Span 组成
- TraceID:每个Trace有⼀个唯⼀的 Trace ID来标识,⽤于关联跨服务的⽇志和监控数据
- Span:Trace的基本单元。代表请求在单个服务节点上的处理过程(如下单,⽀付,数据库查询等),包含操作名称,耗时等数据。
类似快递包裹的物流追踪
我们可以看到物流轨迹中,看到包裹在运转过程中的记录,比如包裹经过了哪些转运节点,在每个转运节点花费了多少时间,派送是否有异常等
链路追踪可以理解为给复杂的⽹络请求画"流程图"⸺它能清晰记录⼀次操作在系统中经过了哪些服务,每个环节耗时多少,是否有异常。
Trace:整个物流链路
TraceID:快递单号
Span:包裹每经过⼀个转运中心,就会⽣成⼀个记录,记录包裹到达时间,状态等信息,所有span通过TraceId关联,最终形成快递的物流轨迹
2.链路追踪的作用
在微服务与分布式架构中,系统复杂度显著提升,会⾯临较多挑战,链路追踪在分布式架构中,有以下作用:
- 保障系统可⽤性与稳定性
分布式系统中,服务依赖的复杂性使得局部故障可能迅速扩散。链路追踪⼯具会通过实时采集CPU、内存、请求成功率等指标,可主动发现异常,并在达到阈值时触发告警。帮助团队在用户感知前介⼊处理,避免系统雪崩。 - 优化性能与资源利⽤率
链路追踪⼯具通过记录请求的完整调⽤链(Trace),将每个服务节点的处理耗时可视化。这种细粒度分析帮助开发者精准识别慢调⽤(如服务A的HTTP请求耗时占⽐ 80%)并进⾏优化。 - 提升故障排查效率
传统⽇志排查需在多台服务器间⼈⼯拼接线索,耗时且易遗漏关键信息。追踪⼯具为每个请求分配唯⼀Trace ID,将跨服务的⽇志,错误信息关联为统⼀视图,帮助快速定位故障节点(如识别数据库查询超时或第三⽅接⼝异常) - 理解服务依赖与拓扑
分布式系统服务依赖关系动态变化,⼈⼯维护依赖图谱成本⾼,可以借助链路追踪⼯具⾃动⽣成服务拓扑图,展示服务间调⽤频率与成功率,辅助容量规划与架构治理。
二.为什么选择SkyWalking
链路追踪这个技术已经⽐较成熟了,市⾯上也有很多链路追踪的产品,接下来介绍⼏种业界主流的链路追踪产品
- Zipkin
- CAT
- SkyWalking
1. ZipKin
Zipkin是由Twitter开发并开源的⼀款分布式链路追踪产品,基于Google的Dapper论⽂设计,旨在帮助开发者监控和排查微服务架构中的请求链路问题。
Zipkin早期主要⽤于Twitter内部解决分布式系统调⽤链路可视化难题,后逐渐被Netflix、阿⾥巴巴等企业采⽤并推广。
2015年成为Apache孵化器项⽬,⽀持多种存储后端(如MySQL,Elasticsearch、内存等)及多语⾔客户端。随着微服务架构普及,Zipkin成为链路追踪领域的标准⼯具之⼀,常与SpringCloud等⽣态集成。
⽬前GitHub收获17.2K+ Star,3100+ Forks,被全球上百家公司采⽤,覆盖电商,⾦融,云计算等多个⾏业。
开源地址:GitHub - openzipkin/zipkin: Zipkin is a distributed tracing system
2.CAT
CAT(Central Application Tracking)是⼀个比较早的分布式监控产品,是美团点评在2011年底基于Java开发的⼀套开源的分布式实时监控系统,⽬前已经覆盖了美团点评的外卖,酒旅,出行,⾦融等核心业务线,几乎已经接⼊美团点评的所有核⼼应⽤。
CAT⾃从2014年开源,GitHub收获18.9K+ Star,5400+ Forks,被 100+公司企业使⽤,其中不乏携程,陆⾦所,猎聘⽹,平安等业内知名公司.
开源地址
3.SkyWalking
Apache SkyWalking 是由个⼈吴晟(华为开发者)于2015年发起的开源应⽤性能监控(APM)系统,于2017年进⼊ Apache 孵化器,成为国内⾸个由个⼈主导进⼊ Apach的开源项⽬,并于2019年正式毕业成为Apache 顶级项⽬,标志着其技术成熟度与社区认可度达到新⾼度。
其发展轨迹从个⼈项⽬逐步演变为全球顶级的分布式系统监控解决⽅案,背后离不开开源社区的持续贡献(如华为、阿⾥巴巴等企业的⽀持)。
SkyWalking专为微服务及分布式架构设计,现已成为全球领先的可观测性解决⽅案。特点是⽀持多种插件,UI功能较强,接⼊端⽆代码侵⼊。⽬前GitHub收获24.3K+Star,6600+Forks,被全球多家知名企业应⽤于⽣产环境。
开源地址:github.com
官⽅⽂档:ApacheSkyWalking
资料参考
4. 特点对⽐
综上:
Zipkin适合需要快速搭建链路追踪的中⼩型团队,对深度监控和业务分析⽀持有限,CAT适合中⼤企业,对报表以及监控粒度要求较⾼SkyWalking 综合实⼒较强,⽆侵⼊,多语⾔且性能较优,⾃⾝包含⽐较丰富的报表及告警⽀持,并且⽀持
插件定制开发(难度较⼤)
三.术语介绍
1.APM
APM:Application Performance Monitor,应⽤性能监控。APM指通过收集,分析和可视化应⽤程序的运⾏时数据(如响应时间、吞吐量、错误率等),帮助开发者和运维团队优化系统性能的技术体系。上述CAT 和SkyWalking就是APM⼯具.
2. OAP
OAP: Observability Analysis Platform,观测分析平台。
SkyWalking的架构通常包括三个主要组件:探针(Agent),后端(Backend)和前端(UI)。其中OAP是后端的重要组成部分,负责接收、处理、存储来⾃探针的可观测性数据,并⽣成聚合指标.
3.Agent
Agent:探针。轻量级数据采集组件,通过字节码植⼊技术(Bytecode Instrumentation)⽆侵⼊式收集应⽤程序的运⾏时数据。
SkyWalking提供了Java,Python,Go,NodeJS,PHP等语⾔的探针
4.UI
UI:可视化界⾯.
通过RESTful API 从 OAP 获取数据,⽀持图表化展⽰与交互式筛选,提供Web控制台,展⽰服务拓扑、调⽤链路、实时指标、告警信息等.
5. Metrics
Metrics:指标,⽐如服务响应时间,服务成功率等.
6. Endpoint
Endpoint:服务实例中⽤于接收和处理外部请求的具体⼊⼝点,是⽐service更细粒度的监控单元,⽤于描述服务内部的接⼝或⽅法级别的访问路径.
四.安装部署
1. 下载安装SkyWalking
1)下载
官⽅下载地址
分别下载:SkyWalking APM(10.2.0) 和Java Agent(9.4.0),从8.8.0之后,agent和apm的安装分开了,需要分开安装apm和agent
找不到相应版本的话,可以去历史版本中找APM 历史版本和Java Agent历史版本
2)解压
- 解压apm,新建⼀个agent⽂件夹
- 解压agent,把内容复制到上⼀步创建的agent⽂件夹中
2. 数据库选型及配置
SkyWalking⽀持多种存储选项,简单介绍以下⼏种
- H2
⾃2015年以来,H2⼀直作为SkyWalking的默认存储选项,旨在简化用户⾸次安装的体验。其内存模式为用户提供了⼀种⽆需额外配置即可本地快速上⼿的⽅式,⾮常适合学习,但是在⽣产环境⾮常受限,⽐如H2的内存模式通常会在运⾏⼤约20分钟后丢失数据,更糟糕的是,这种⾏为没有任何预警,导致⽆法⻓期使⽤。所以官⽅从2025年宣布H2将不再作为存储选项被⽀持。取⽽代之的是BanyanDB - MySQL
Skywalking⼀直⽀持MySQL为存储选项,MySQL对于中⼩规模的数据友好,部署和运维成本低,适合已有MySQL基础设施的团队,但是分库分表复杂度⾼,⽆法适应千亿级数据的分布式存储需求。但对时间序列数据的聚合查询效率远低于ES,复杂查询易成为瓶颈。适合学习和测试环境,或者数据量极⼩的环境. - Elasticsearch
在2025年之前,ES⼀直作为官⽅推荐的⽣产环境使⽤的存储选项,ES基于倒排索引和分⽚机制,擅⻓处理海量时序数据的查询与聚合分析,可通过集群分⽚应对PB级数据存储需求。⽽且社区⽀持⼴泛,但是ES的运维成本较⾼,需要独⽴部署ES集群,对资源消耗⼤,使得ES的性价⽐不是很⾼。 - BanyanDB
BanyanDB脱胎于SkyWalking社区,主要⾯向APM领域,专为处理Metrics(指标)、Tracing(追踪)、Logging(⽇志)三类可观测性数据设计。BanyanDB专为云原⽣架构设计,能够处理更⼤的⼯作负载,⽆需担⼼数据丢失,⽽且设置⾮常简单,降低了新用户的使⽤⻔槛。
作为SkyWalking的原⽣数据库,BanyanDB⽬前还处于⾼速研发的阶段。随着BanyanDB⼦项⽬的不断发展,SkyWalking官⽅宣布,BanyanDB 0.8已经完全⽣产可⽤,是⽣产环境的理想选择。
3.修改配置
1) 修改端⼝号(按需)
SkyWalking UI的默认端⼝号是8080,如果和现有进程冲突了,可以进⾏修改。修改⽂件: /apache-skywalking-apm-bin/webapp/application.yml
serverPort: ${SW_SERVER_PORT:-8080}
# Comma seperated list of OAP addresses.
oapServices: ${SW_OAP_ADDRESS:-http://localhost:12800}
zipkinServices: ${SW_ZIPKIN_ADDRESS:-http://localhost:9412}
Skywalking-oap-server 服务(OAP模块的实际运⾏实例)启动后会暴露11800和12800两个端⼝
11800: grpc端⼝,接受SkyWalking Agent的监控数据
12800: REST API端⼝,提供RESTful API 服务,供 SkyWalking UI或其他外部系统调⽤,⽤于查询监控数据.
2) 创建数据库
CREATE DATABASE skywalking;
3) 修改存储后端为MySQL
连接mysql需要在 /apache-skywalking-apm-bin/oap-libs 这个⽬录下放⼊mysqlconnector-java的包(可以在之前写的项目中找到对应的MySQL的Maven依赖,打开对应的文件目录)
修改存储配置
配置⽂件路径: /apache-skywalking-apm-bin/config/application.yml
storage:selector: ${SW_STORAGE:mysql}
修改mysql相关配置:
mysql:properties:jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/skywalking?rewriteBatchedStatements=true&allowMultiQueries=true"}dataSource.user: ${SW_DATA_SOURCE_USER:你的mysql账户}dataSource.password: ${SW_DATA_SOURCE_PASSWORD:你的mysql密码}dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}dataSource.prepStmtCacheSize:${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}dataSource.prepStmtCacheSqlLimit:${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}dataSource.useServerPrepStmts:${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000}asyncBatchPersistentPoolSize:${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4}
4. 启动SkyWalking
启动⽂件: /apache-skywalking-apm-bin/bin/startup.bat 双击运⾏
访问:http://127.0.0.1:port/marketplace,port改成上⾯UI设置的端⼝号
显示该⻚⾯,说明启动成功(第⼀次启动需要做很多初始化⼯作,会⽐较慢)
五.SkyWalking快速开始
1.服务准备
使⽤前⾯seata组件时的项⽬,修改项⽬名称即可,确认所有服务都是正常的。
2.服务接⼊以order-service为例
添加启动参数,通过 -javaagent 参数进⾏配置SkyWalking Agent来跟踪微服务
-javaagent:D:\soft\apache-skywalking-apm-10.2.0\apache-skywalking-apmbin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=order-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-javaagent:后⾯换成⾃⼰的路径
-Dskywalking.agent.service_name :服务名称
-Dskywalking.collector.backend_service :SkyWalking服务器配置
启动完成之后,就可以在SkyWalking的UI上看到服务列表了
点击左侧[服务]
同上,完成其他服务接⼊skywalking
3.接⼝请求
发起接⼝请求
[POST] http://127.0.0.1:8083/order/create
{
"userId": 1004,
"commodityCode":2004,
"count": 1,
"money": 1
}
观察⻚⾯,会出现⼀些指标
六.UI介绍
1.⻚⾯指标介绍
服务接⼊Skywalking后,当有请求时,UI⻚⾯会显⽰服务相关的指标
- Service Apdex:当前服务的评分,量化用户对服务性能满意度的标准化指标,反映用户体验的质量.
- Service Success Rate:服务请求成功率
- Service Avg Response Time(ms):服务平均响应延时(单位ms)
- Service Load (calls/min):分钟请求数
- Endpoint Success Rate:当前端点的成功率
- Endpoint AvgResponse Time(ms):端点的平均响应时⻓
- Endpoint Load (calls / min):每个端点(URL)的请求次数
2 模拟接⼝
为了⽅便观察,我们新增⼀个订单查询的接⼝order-service
OrderController
@RequestMapping("/query/{orderId}")public ResponseEntity<OrderInfo> queryOrder(@PathVariable Integer orderId) throws InterruptedException {log.info("查询订单, orderId:{}", orderId);Thread.sleep(new Random().nextInt(100));if (orderId%5==0){throw new RuntimeException("模拟异常");}if (orderId==9){Thread.sleep(2000);}OrderInfo orderInfo= orderService.queryById(orderId);return ResponseEntity.status(HttpStatus.OK).body(orderInfo);}
OrderService
OrderInfo queryById(Integer orderId);
OrderServiceImpl
@Override
public OrderInfo queryById(Integer orderId) {
return orderMapper.selectById(orderId);
}
3.观察指标
重启服务,使⽤JMeter模拟请求,随机访问上述接⼝,请求路径: /order/query/${__Random(1,20)} ,观察UI⻚⾯,指标会发⽣相应变化
1)Service
服务概况:
会显示接⼊Skywalking的服务,已经服务的概况
ServiceNames: 服务名称
Load(calls/min): 每分钟访问次数
Success Rate(%): 请求成功率
Latency(ms): 服务请求延迟时间(此处为服务平均响应时间)
Apdex: 当前服务评分
2)服务详情
告警信息
点击服务名称,会显⽰相应服务的详情
上⾯是服务告警相关信息,点击会⾼亮显示告警时间段的指标
服务概况
- Service Avg Response Time(ms): 服务平均响应延时(单位ms)
- Service Apdex: 当前服务评分
- Service ResponseTime Percentile(ms): 服务响应时间百分⽐,通过分位数(如P99,P95,P90,P75, P50)反映不同⽐例请求的延迟情况.如P99=300ms表示99%的请求延迟低于300ms
- Service Load (calls/min): 分钟请求数
- Success Rate (%): 分钟请求成功百分⽐
- Message Queue ConsumingCount: 消息队列消耗计数
- Message Queue Avg Consuming Latency(ms): 消息队列平均消耗延迟(单位ms)
- Service Instances Load (calls/min): 服务节点每分钟请求次数
- Slow Service Instance (ms): 服务节点的最⼤延时
- Service Instance Success Rate(%): 每个服务实例的请求成功率
- Endpoint Load in Current Service(calls/min): 每个端点(URL)的请求次数
- Slow Endpoints in Current Service(ms): 当前端点(URL)的慢响应时间
- Endpoint Success Rate in Current Service(%): 当前端点(URL)的成功响应请求占⽐
3)Instance
显示所选服务的实例节点
4)Endpoint
按端点聚合,显⽰端点的请求次数/成功率/延迟
5)Topology
显示服务的拓扑图
发起创建订单的请求,拓扑图就会增加新的服务调⽤关系
6)Trace
左侧为端点列表,蓝⾊表示正常请求,红⾊表示异常请求,右侧显示请求的追踪链表,各个节点的调⽤顺序及时间等
右侧可以切换不同的显示格式
这个⻚⾯会显示每个中间节点的执⾏时间,以及执⾏占⽐等,⽅便我们进⾏性能分析
4. 数据库指标
Skywalking 也会提供数据库相关的监控指标
可以看到数据库的列表,已经数据库的概况
1)指标介绍
点击数据库,可以看到执⾏数据库的详情
- Database Avg Response Time (ms): 数据库平均响应时间
- Database Access Successful Rate (%): 数据库访问成功率
- Database Traffic(calls/min): 数据库流量(每分钟的请求次数)
- DatabaseAccess Latency Percentile (ms): 数据库访问延迟(百分位数)-
- Slow Statements(ms): 慢SQL 列表
2)模拟慢SQL
代码修改
- OrderController
@RequestMapping("/slowSql")
public String slowSql(int time){
orderService.selectSleep(time);
return "success";
}
- OrderService
void selectSleep(int time);
- OrderServiceImpl
@Override
public void selectSleep(int time) {orderMapper.selectSleep(time);
}
- OrderMapper
@Mapper
public interface OrderMapper extends BaseMapper<OrderInfo> {
@Select("select sleep(#{time})")
Integer selectSleep(int time);
}
访问接⼝,测试http://127.0.0.1:8083/order/slowSql?time=2,也可以通过Jemter来模拟接⼝请求,请求路径: /order/slowSql?time=${__Random(1,5)} ,观察⻚⾯,会显示出来慢SQL
七.⾃定义追踪
Skywalking默认会对接⼝提供追踪,如果我们希望对项⽬中的业务⽅法进⾏链路追踪,就需要⾃定义追踪了.
1.添加依赖
<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>9.4.0</version>
</dependency>
2.添加注解@Trace
在需要监控的⽅法上添加 @Trace 注解,就会把⽅法加⼊链路追踪⾥,会⾃动⽣成span并记录⽅法的执⾏耗时及调⽤关系
@Override
@Trace
public OrderInfo queryById(Integer orderId) {return orderMapper.selectById(orderId);
}
如图所示:
@Trace ⽀持⾃定义span名称( operationName )以增强可读性
@Override
@Trace(operationName = "queryById")
public OrderInfo queryById(Integer orderId) {return orderMapper.selectById(orderId);
}
添加之后,追踪图如下所示:
3.附加业务信息
在 SkyWalking 中,可以使⽤ @Tag 或者 @Tags 在⾃定义链路追踪中附加关键业务或上下⽂信息的注解,⽐如记录参数和返回信息。在⽅法上使⽤ @Tag 或 @Tags 注解,指定需捕获的数据类型
- @Tag
@Override
@Trace(operationName = "queryById")
@Tag(key="orderId", value = "arg[0]") //捕获第⼀个参数
public OrderInfo queryById(Integer orderId) {
return orderMapper.selectById(orderId);
}
可以看到span的标记
2. @Tags
@Trace
@Tags({@Tag(key = "response", value = "returnedObj"), //捕获返回值@Tag(key = "request", value = "arg[0]") //捕获第⼀个参数
})
public OrderInfo queryById(Integer orderId) {return orderMapper.selectById(orderId);
}
arg[n]: 表示⽅法的第n个输⼊参数(从0开始).
returnedObj: 表示⽅法的返回值.
添加之后,观察span的标记
八.性能剖析
性能剖析功能是⼀种针对分布式系统代码级性能的动态分析技术,SkyWalking提供了追踪分析的功能。
可以查看请求调⽤链中具体⽅法或者代码块的执⾏耗时,⽤于快速识别⾼耗时⽅法(如慢SQL查询等),定位服务调⽤链(Trace)中具体 Span(单个操作节点)的性能问题.
1.新建任务
端点: 需要分析的端点的名称
监控时间: 采集数据的开始时间
监控持续时间: 监控采集多⻓时间
起始监控时间: 多少秒后进⾏采集
监控间隔: 多⻓时间采集⼀次
最⼤采集数: 最⼤采集多少样本
2.观察剖析结果
发起请求,观察链路的追踪情况
通过这个链路追踪,可以查看各个span的执⾏时间,选择需要分析的span,点击 [分析]
就会出现线程栈信息
在线程栈信息中,可以看到具体是哪部分代码引起的慢性能
九.⽇志上传
SkyWalking不仅⽀持链路追踪,还可以集成⽇志数据,帮助用户在⼀个平台上统⼀查看⽇志和追踪信息,基于Trace ID 实现⽇志与请求链路的⾃动关联,快速定位故障上下⽂。
配置参考:logback plugin
1.引⼊依赖
<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>9.4.0</version>
</dependency>
2.⽇志配置
添加 logback-spring.xml ⽂件
- Logback 框架默认加载的配置⽂件名为 logback.xml ,该名称适⽤于⾮Spring Boot 应⽤.
- Spring Boot默认会识别logback-spring.xml,,这是Spring Boot推荐的⽅式,优先级⾼于默认logback.xm,⽀持Spring扩展特性(如 ${spring.profiles.active})
- 若同时存在 logback.xml 和 logback-spring.xml ,Spring Boot优先加载logbackspring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"><!-- ⽇志格式化, 配置 %tid 占位符 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layoutclass="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><!-- 通过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"><layoutclass="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>
重启服务,观察⽇志
观察Skywalking UI的Log选项,也提供了⽇志查询
可以根据TraceID 进⾏⽇志搜索,并跳转到具体的追踪⻚⾯
十.告警管理
除了指标的监测之外,SkyWalking还提供了告警功能。当系统出现异常时(如接⼝响应慢,成功率低),⾃动触发通知,帮助研发⼈员或者运维⼈员快速定位问题类似烟雾报警器,⼀旦检测到烟雾(系统异常),⽴刻发出警报声(通知),提醒你处理⽕灾(解决问题)
点击可以看到告警详情
1.告警规则
SkyWalking的告警系统预先定义了⼀部分告警规则,在config/alarm-settings.yml⽂件中,用户也可以⾃定义告警规则。
参考
# Sample alarm rules.
rules:
# Rule unique name, must be ended with `_rule`.
service_resp_time_rule:
# A MQE expression, the result type must be `SINGLE_VALUE` and the root
operation of the expression must be a Compare Operation
# which provides `1`(true) or `0`(false) result. When the result is
`1`(true), the alarm will be triggered.
expression: sum(service_resp_time > 1000) >= 1
period: 10
silence-period: 5
message: Response time of service {name} is more than 1000ms in 3 minutes
of last 10 minutes.
配置说明:
- XXXX_rule:规则名称,必须以"_rule"结尾
- expression:告警表达式,结果为1时,触发报警
- period:告警周期,评估指标的时间⻓度(以分钟为单位)
- silence-period:静默期,在告警触发后,多⻓时间内不再触发。
在Time-N(TN)触发告警后,在"TN->TN+period"时间段内保持静默。
默认情况下,它的⼯作⽅式与period相同。同⼀告警在⼀个周期内只能触发⼀次 - message:告警消息
为⽅便起⻅,SkyWalking提供了⼀个默认的alarm-setting.yml,包括以下规则:
- 过去3分钟内服务平均响应时间超过1秒。
- 最近2分钟服务成功率低于80%。
- 过去3分钟内超过1秒的服务响应时间百分位数
- 服务实例在过去2分钟内的平均响应时间超过1秒,并且实例名称与正则表达式匹配。
- 终端节点在过去2分钟内的平均响应时间超过1秒。
- 过去2分钟内数据库访问平均响应时间超过1秒。
- 终端节点关系过去2分钟内超过1秒的平均响应时间。
2.Webhook
webhook是⼀种允许应⽤程序向外部系统实时推送事件或数据的机制,通常通过HTTP回调实现,从⽽实现跨系统⾃动化的信息传递。
核⼼特征:
- 事件驱动:当预设条件触发时(如告警触发、数据更新),主动向⽬标URL发送HTTP请求(通常为POST)
- 轻量级集成:接收⽅只需提供⼀个可访问的HTTP端点即可接收数据,⽆需轮询查询
- 灵活扩展:适⽤于告警通知,流程触发,数据同步等场景
1) SkyWalking的WebHook实现
SkyWalking提供了WebHook的⽅式,主要⽤于告警通知。其核⼼功能与配置要点如下:
- 告警触发与推送
当监控指标(如响应时间、错误率等)达到告警规则阈值时,SkyWalking会⽣成告警事件,⾃动把告警信息封装为JSON格式,通过HTTP的⽅式发送⾄预设的WebHook接收地址。
JSON格式定义参考:
List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>- scopeId、scope:告警⽬标的监控范围,参考org.apache.skywalking.oap.server.core.source.DefaultScopeDefine 中定义
- Name:告警⽬标的名称,如服务名、端点名等,参考:Alerting
- id0:⽬标实体的主要ID,通常是数据库中的主键
- id1:⽬标实体的次要ID(可选),⽤于更精确的标识
- ruleName:触发告警的规则名称
- alarmMessage:具体的告警消息内容
- startTime:告警触发的时间戳(毫秒)
- 标签:标签列表,包含与告警相关的附加信息
- 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)WebHook实践
(1)配置WebHook
配置 alarm-settings.yml,然后重启
hooks:webhook:default:is-default: trueurls:- http://127.0.0.1:8084/alarm/handler
(2)接⼝开发
- 创建项⽬ alarm-service,⽤来接收WebHook
- 核⼼代码
- 配置⽂件
server:
port: 8084
logging:
pattern:
dateformat: HH:mm:ss:SSS
- 接收告警信息实体类
对应数据库 alarm_record_XXX表,AlarmMessage
参考1
参考2
@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;@Dataclass Tag{private String key;private String value;}
}
AlarmController
import com.bit.alarm.entity.AlarmMessage;
import lombok.extern.slf4j.Slf4j;
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
@RequestMapping("/alarm")
public class AlarmController {@Autowiredprivate Mail mail;@RequestMapping("/handler")public String handler(@RequestBody List<AlarmMessage> alarmMessages){log.info("接收到告警: {}", alarmMessages);mail.sendMail("to_lcf@126.com", buildContent(alarmMessages));return "接收到告警";}
}
重启服务
3. 使⽤JMeter模拟请求,触发告警
在SkyWalking UI告警⻚⾯收到告警后,观察后端⽇志,⽇志显示有收到告警信息
3)配置邮件告警
SkyWalking的WebHook功能,会通过HTTP的⽅式,把告警信息发送⾄预设的WebHook接收地址,我们可以借此功能在这个接⼝⾥实现发送邮件或者短信等功能,从⽽达到告警主动通知。
接下来以邮件为例
参考:Spring Boot发送邮件
- 添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>
- 定义邮件配置项
spring:mail:host: smtp.qq.com # 指定邮件服务器地址# 登录账户username: 账户# 登录密码password: 授权密码# 端口port: 465# 默认编码default-encoding: UTF-8# 使用的协议protocol: smtps# 其他的属性properties:"personal": "告警系统""subject": "告警通知"
- 定义邮件发送⼯具
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
@Configuration
@ConditionalOnProperty(prefix = "spring.mail",name = "host")
public class MailConfig {@Beanpublic Mail mail(MailProperties mailProperties, JavaMailSender mailSender){return new Mail(mailProperties, mailSender);}
}
package com.bit.alarm.mail;import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;@Slf4j
@Configuration
public class Mail {@Autowiredprivate JavaMailSender javaMailSender;@Autowiredprivate MailProperties mailProperties;public void sendMail(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));// 收件人邮箱helper.setTo(to);// 邮件标题helper.setSubject(mailProperties.getProperties().getOrDefault("subject", "告警通知"));// 邮件正文,第二个参数表示是否是HTML正文helper.setText(content, true);// 发送javaMailSender.send(message);}catch (Exception e){log.error("邮件发送失败, e:", e);}}
}
- 发送邮件
package com.bit.alarm.controller;import com.bit.alarm.entity.AlarmMessage;
import com.bit.alarm.mail.Mail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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
@RequestMapping("/alarm")
public class AlarmController {@Autowiredprivate Mail mail;@RequestMapping("/handler")public String handler(@RequestBody List<AlarmMessage> alarmMessages){log.info("接收到告警: {}", alarmMessages);mail.sendMail("3438981745@qq.com", buildContent(alarmMessages));return "接收到告警";}private String buildContent(List<AlarmMessage> alarmMessages) {StringBuilder builder = new StringBuilder();builder.append("告警详情:");for (AlarmMessage message: alarmMessages){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.接⼊⻜书
SkyWalking的WebHook功能,也集成了第三⽅系统,可以通过简单的配置,推送告警⾄Slack,企业微信,钉钉,飞书等。接下来⻜书为例,来演示接⼊飞书
参考:接⼊⻜书
- 注册⻜书账号
- 创建机器⼈
打开⻜书群组→点击右上⻆「设置」→「群机器⼈」→「添加机器⼈」→选择「⾃定义机器⼈」配置机器⼈名称,获取⽣成的 Webhook URL(格式为https://open.feishu.cn/openapis/bot/v2/hook/xxxxxx )
- 配置webHook
hooks:feishu:default:is-default: truetext-template: |{"msg_type":"text","content": {"text": "Apache SkyWalking Alarm: \n %s."}}webhooks:- url: https://open.feishu.cn/open-apis/bot/v2/hook/f422708b-b41d-4911-
87ed-aa1b22131ad9secret: dCNQubWsVSTNytjCvmmk5f
4.测试告警推送
模拟请求,触发告警,观察⻜书收到告警消息