Spring Cloud系列—SkyWalking链路追踪

上篇文章:

Spring Cloud系列---Seata分布式事务解决方案TCC模式和Saga模式https://blog.csdn.net/sniper_fandc/article/details/149947829?fromshare=blogdetail&sharetype=blogdetail&sharerId=149947829&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

目录

[1 链路追踪](#1 链路追踪)

[1.1 概念](#1.1 概念)

[1.2 作用](#1.2 作用)

[2 常见组件对比](#2 常见组件对比)

[3 SkyWalking安装部署](#3 SkyWalking安装部署)

[3.1 下载APM和Agent](#3.1 下载APM和Agent)

[3.2 选择存储数据库](#3.2 选择存储数据库)

[3.3 启动SkyWalking](#3.3 启动SkyWalking)

[4 Spring Cloud集成SkyWalking](#4 Spring Cloud集成SkyWalking)

[4.1 集成SkyWalking](#4.1 集成SkyWalking)

[4.2 指标介绍](#4.2 指标介绍)

[4.2.1 服务总览](#4.2.1 服务总览)

[4.2.2 具体服务](#4.2.2 具体服务)

[4.2.3 链路追踪Trace](#4.2.3 链路追踪Trace)

[4.2.4 数据库](#4.2.4 数据库)

[5 SkyWalking自定义追踪](#5 SkyWalking自定义追踪)

[5.1 引入依赖](#5.1 引入依赖)

[5.2 注解@Trace](#5.2 注解@Trace)

[5.3 注解@Tag和@Tags](#5.3 注解@Tag和@Tags)

[6 SkyWalking性能剖析](#6 SkyWalking性能剖析)

[7 SkyWalking日志上传](#7 SkyWalking日志上传)

[7.1 引入依赖](#7.1 引入依赖)

[7.2 添加日志配置](#7.2 添加日志配置)


1 链路追踪

1.1 概念

链路追踪是分布式系统对请求路径的流程追踪,通过记录请求在多个服务间的通信路径、耗时、状态等信息,形成完整的调用链视图。每个请求主要是通过唯一标识(TraceID),类似快递单号;串联跨服务的调用单元(Span),类似快递中转站;并借助上下文传递(Context)实现链路连续性。

1.2 作用

(1)保障系统可用性与稳定性:链路追踪可以及时采集CPU、内存和请求成功率等信息,在达到阈值时警告开发人员,及时发现服务问题,从而将故障服务还未扩散或被用户感知时就排查掉。

(2)优化性能与资源利用率:请求的完整调用链可以观察哪个节点处理最慢,从而针对该节点进行性能优化。

(3)提升故障排查效率:链路追踪工具为每个请求分配唯一的Trace ID,将跨服务的日志、错误信息等关联为统一视图,帮助快速定位故障节点。比如识别数据库慢查询或第三方接口调用异常)

(4)理解服务依赖关系和拓扑:复杂的微服务系统各服务之间调用关系复杂,利用链路追踪可以生成服务拓扑图,帮助理清服务依赖关系,从而便于优化系统架构。

2 常见组件对比

|--------|------------------------------------------|----------------------------------|--------------------------------------------|
| | Zipkin | CAT | SkyWalking |
| 接入复杂度 | 轻量级,集成Spring Cloud Sleuth | 需要代码埋点 | 通过Java agent启动,代码无侵入 |
| 数据粒度 | 接口级 | 代码级 | 方法级(RPC、HTTP) |
| 支持语言 | Java、C#、Python、Nodejs、Golang、Ruby、Scala等 | Java、C/C++、Python、Nodejs、Golang等 | Java、Python、Nodejs、PHP、Golang、Ruby等 |
| 调用链可视化 | 有 | 有 | 有 |
| 聚合报表 | 少 | 非常丰富 | 较丰富 |
| 服务依赖图 | 简单 | 简单 | 好 |
| 告警支持 | 无 | 支持 | 支持 |
| 存储机制 | 内存、ES、MySQL等 | mysql(报表),本地文件/HDFS(调用链) | ES、MySQL、banyandb、PostgreSQL等(最新版本已移除H2存储) |
| 社区支持 | 文档丰富,但是国外主流、功能迭代较慢 | 社区活跃低,文档一般,国内大厂用 | 社区活跃更新频繁 |
| 优点 | 轻量,部署简单,适合SpringCloud微服务快速集成 | 功能全面(日志采集、报警、业务、报表),适合大厂综合监控 | 非侵入,Apache 背书,社区活跃 |
| 缺点 | 报表能力弱,功能单一 | 代码侵入高,社区不活跃 | 插件开发门槛高 |

3 SkyWalking安装部署

SkyWalking是个人(吴晟)开源的应用性能监控(APM)系统,其涉及到几个常用的概念:

****APM(Application Performance Monitor):****应用性能监控,通过收集、分析和可视化应用运行时的数据,帮助运维及时分析系统性能和优化系统。CAT和SkyWalking就是APM,而Zipkin不是APM。

****OAP(Observability Analysis Platform):****观察分析平台,SkyWalking由Agent(探针)、UI(前端)、Backend(后端)组成,OAP就是后端的重要组成部分,通过接收、处理和存储来自Agent(探针)的数据,然后生成聚合指标。

****Agent:****探针,轻量级数据采集组件,通过字节码植入技术(Bytecode Instrumentation,直接修改字节码,无需添加代码)无侵入式收集应用数据。

****UI:****可视化界面,也就是前端,通过RESTful来远程从OAP获取数据并可视化渲染到页面上,支持图表等多种方式,提供Web控制台,展示服务拓扑、调用链路、实时指标、告警信息等。

****Metrics:****指标,比如请求响应时间、成功率等。

****Endpoint:****服务实例中用于接收和处理外部请求的具体入口点,是比service更细粒度的监控单元,用于描述服务内部的接口或方法级别的访问路径。可以简单理解为接口。

3.1 下载APM和Agent

从SkyWalking后,APM和Agent下载就分开了,这里分别下载10.2.0的APM和9.4.0的Agent:

https://skywalking.apache.org/downloads/

下载完后解压到本地:

为了便于管理,可以在apm目录下创建agent目录,并把下载的agent复制到agent目录下:

3.2 选择存储数据库

可选的数据库有如下类型:

****(1)H2:****2025年以前的SkyWalking的默认存储,基于内存。但是H2内存模式在运行20分钟以上就会数据丢失且无告警,因此官方在2025年以后永久移除了该存储选项。

****(2)MySQL:****对于中小规模的数据友好,部署和运维成本低,适合已有MySQL基础设施的团队或小规模数据环境。但是分库分表复杂度高,无法适应千亿级数据的分布式存储需求,但对时间序列数据的聚合查询效率远低于ES,复杂查询易成为瓶颈。

****(3)Elasticsearch:****ES基于倒排索引和分片机制,擅长处理海量时序数据的查询与聚合分析,可通过集群分片应对PB级数据存储需求,并且社区支持广泛,但是ES的运维成本较高,需要独立部署ES集群,对资源消耗大,使得ES的性价比不是很高。

****(4)BanyanDB:****主要应用就是APM领域,专为处理Metrics(指标)、Tracing(追踪)、Logging(日志)三类可观测性数据设计。BanyanDB专为云原生架构设计,能够处理更大的工作负载,无需担心数据丢失,而且设置非常简单,降低了新用户的使用门槛。作为SkyWalking的原生数据库,BanyanDB目前还处于高速研发的阶段,随着BanyanDB子项目的不断发展,SkyWalking官方宣布,BanyanDB 0.8已经完全生产可用,是生产环境的理想选择。

这里选择MySQL作为存储。首先需要创建数据库,然后在SkyWalking的配置文件中修改存储配置:

sql 复制代码
CREATE DATABASE skywalking;

并且,需要引入MySQL的连接依赖,该依赖可以通过以往项目中引入的MySQL依赖在Maven本地仓库找到,将jar包复制到apache-skywalking-apm-bin\oap-libs:

修改配置文件,路径apache-skywalking-apm-bin\config下的application.yml文件,需要修改存储为mysql配置:

然后注意修改JDBC连接的数据库名、user、password信息:

3.3 启动SkyWalking

由于SkyWalking的默认端口号是8080,在JavaWeb开发时通常会和Tomcat的端口号冲突,因此启动前需要修改端口号。在apm安装路径的apache-skywalking-apm-bin\webapp下打开application.yml文件修改:

在apache-skywalking-apm-bin\bin找到启动命令startup.bat双击启动即可:

访问http://127.0.0.1:8999/marketplace:

4 Spring Cloud集成SkyWalking

4.1 集成SkyWalking

在启动服务时,添加启动参数VM options:

bash 复制代码
-javaagent:D:\javaee_study\apache-skywalking-apm-10.2.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar -Dskywalking.agent.service_name=order-service -Dskywalking.collector.backend_service=127.0.0.1:11800

**-javaagent:**后面跟Java agent的安装路径,即移动到apm中的agent。

**-Dskywalking.agent.service_name:**后面跟服务名称。

**-Dskywalking.collector.backend_service:**后面跟skywalking启动的apm服务。

启动服务后在UI界面可以观察到请求的路径和链路拓扑结构:

4.2 指标介绍

4.2.1 服务总览

Service Apdex:当前服务的评分,量化用户对服务性能满意度的标准化指标,反映用户体验的质量。

Service Success Rate:服务请求成功率。

Service Avg Response Time (ms):服务平均响应延时(ms)。

Service Load (calls / min):分钟请求数。

Endpoint Success Rate:当前端点的成功率。

Endpoint Avg Response Time (ms):端点的平均响应时长。

Endpoint Load (calls / min):每个端点(URL)的请求次数。

Service Avg Response Time (ms):服务平均响应延时(ms)。

4.2.2 具体服务

Service Apdex:当前服务评分。

Service Response Time Percentile (ms):服务响应时间百分比,通过分位数(如P99、P95、P90、P75、P50)反映不同比例请求的延迟情况。比如P99=300ms表示99%的请求延迟低于300ms。

Service Load (calls / min):分钟请求数。

Success Rate (%):分钟请求成功百分比。

Message Queue Consuming Count:消息队列消耗计数。

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)的成功响应请求占比。

4.2.3 链路追踪Trace

4.2.4 数据库

Database Avg Response Time (ms):数据库平均响应时间。

Database Access Successful Rate (%):数据库访问成功率。

Database Traffic (calls / min):数据库流量(每分钟的请求次数)。

Database Access Latency Percentile (ms):数据库访问延迟(百分位数)。

Slow Statements (ms) :慢SQL列表。对于慢SQL,可以使用jmeter模拟,比如接口采用/order/slowSql?time=${__Random(1,5)}进行请求,表示随机[1,5]范围内时间(ms)进行请求,select sleep(time)。

5 SkyWalking自定义追踪

默认的追踪是接口级别的,因此如果想要对方法级别进行追踪,就需要自定义追踪。

5.1 引入依赖

XML 复制代码
        <dependency>

            <groupId>org.apache.skywalking</groupId>

            <artifactId>apm-toolkit-trace</artifactId>

            <version>9.4.0</version>

        </dependency>

5.2 注解@Trace

@Trace注解添加在想要监控的方法上,该注解会为方法添加一个span,并且支持operationName来命名该span:

java 复制代码
    @Override

    @GlobalTransactional

    @Trace(operationName = "createOrder")

    public Long create(OrderInfo orderInfo) {

        try {

            //插入订单

            orderMapper.insert(orderInfo);

            //扣余额

            accountApi.deduct(orderInfo.getUserId(), orderInfo.getMoney());

            //扣库存

            storageApi.deduct(orderInfo.getCommodityCode(), orderInfo.getCount());

        }catch (Exception e){

            log.error("下单失败, e: ", e);

            throw new RuntimeException("下单失败, e:", e);

        }

        return orderInfo.getId();

    }

5.3 注解@Tag和@Tags

可以直接在方法上添加@Tag注解,能够捕获更细粒度信息,比如方法接收的参数和返回值,arg[n]表示形参列表的第几个参数,returnedObj表示方法返回值。@Tags表示多个@Tag:

java 复制代码
    @Override

    @GlobalTransactional

    @Trace(operationName = "createOrder")

    @Tags({

            @Tag(key = "orderInfo",value = "arg[0]"),

            @Tag(key = "return",value = "returnedObj")

    })

    public Long create(OrderInfo orderInfo)

6 SkyWalking性能剖析

当发现某个方法执行较慢时,如果想要定位到具体哪行代码较慢,就需要使用性能剖析。点击某个具体的服务,然后点击Trace Profilling,新建任务:

当监控采样到请求后,就可以选中某个链路,点击分析,出现相关线程栈信息,根据栈信息就可以定位执行时间最长的代码:

7 SkyWalking日志上传

SkyWalking支持日志上传,通过Trace ID实现日志和链路的关联:

7.1 引入依赖

XML 复制代码
        <dependency>

            <groupId>org.apache.skywalking</groupId>

            <artifactId>apm-toolkit-logback-1.x</artifactId>

            <version>9.4.0</version>

        </dependency>

7.2 添加日志配置

SpringBoot底层默认支持logback日志组件,要上传日志就需要配置logback.xml文件(适用非SpringBoot应用)。SpringBoot推荐和优先加载logback-spring.xml文件,因此配置该文件内容如下:

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">

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

    <!-- 通过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>

    <root level="info">

        <appender-ref ref="STDOUT"/>

        <appender-ref ref="grpc-log"/>

    </root>

</configuration>

appender标签是日志输出的核心组件,该标签中的class属性表示输出到哪,GRPCLogClientAppender表示输出到远程SkyWalking客户端,ConsoleAppender表示输出到控制台。重启服务,观察结果:

还可以通过日志绑定的Trace ID(TID)追踪对应的链路信息,点击左侧蓝色标识也可快速追踪。

下篇文章:

Spring Cloud系列---SkyWalking告警和飞书接入https://blog.csdn.net/sniper_fandc/article/details/149948716?fromshare=blogdetail&sharetype=blogdetail&sharerId=149948716&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link