微服务链路追踪-SkyWalking

微服务链路追踪-SkyWalking

SkyWalking官网地址:https://skywalking.apache.org/

SkyWalking官方文档:https://skywalking.apache.org/docs/main/v8.6.0/readme/

SkyWalking中文文档:https://skyapm.github.io/document-cn-translation-of-skywalking/

SkyWalking是 一个开源的可观测平台, 用于从服务和云原生基础设施收集, 分析, 聚合及可视化数据。

一、SkyWalking环境搭建部属

1. 下载

下载地址:https://skywalking.apache.org/downloads/

这里下载的是SkyWalking APM 8.6.0的版本。

在这里插入图片描述

下载解压。

2. 环境搭建

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

SkyWalking包含:

  • agent和业务系统绑定在一起,负责收集各种监控数据。
  • oap服务,是负责处理监控数据的,比如接受skywalking agent的监控数据, 并存储在数据库中;接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapservice通常以集群的形式存在。
  • webapp的UI服务,前端界面,用于展示数据。

2.1 config/application.yml文件

Skywalking启动后,会有两个服务(oap与UI),oap服务会暴露两个端口号:11800用于收集监控数据的端口,12800用于接收前端请求。

在这里插入图片描述

SkyWalking的默认存储方式为h2,为了持久化可以修改为mysql,elasticsearch等。

在这里插入图片描述

这里我们使用MySQL的存储方式,然后相应的修改下面对应的mysql的配置信息(地址、账号密码等信息)。

在这里插入图片描述

2.2 webapp/webapp.yml

SkyWalking UI服务端口,默认是8080。

在这里插入图片描述

这里修改为8868后,启动访问的地址为 http://127.0.0.1:8868/。

2.3 MySQL持久化

将存储方式修改为MySQL方式后,需要新建对应的数据库,这里时swtest,在SkyWalking启动时会自动建表,需要注意的是,启动脚本中没有mysql驱动包,需要下载后放在oap-libs目录下。mysql-connector-java.jar可以前往https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.21下载,也可以从有依赖mysql的项目仓库中找一个。

项目启动时可能会遇到time zone的服务器时区问题,需要在config/application.yml的mysql信息配置中设置时区,jdbc:mysql://localhost:3306/swtest?serverTimezone=UTC

项目成功启动后数据库如下:

在这里插入图片描述

2.4 日志文件

启动后会生成logs文件夹,日志文件存储在那里。

2.5 SkyWalking接入微服务

SkyWalking是无侵入性的,无需在项目代码中进行配置。只需在项目启动时做些配置。

用IDEA配置:在Configurations中配置VM options。配置如下:

-javaagent:D:/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_NAME=gateway-server

第一行是指定skywalking-agent.jar的文件路径,第二行是指定收集监控数据的地址,第三行是该项目的服务名(自定义,一般使用spring.application.name)。

在这里插入图片描述

用jar包启动配置:

java -javaagent:D:/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_NAME=gateway-server -jar xxx.jar

Linux下启动配置: 可以通过上述java -jar的方式,也可以配置启动脚本:

#!/bin/sh
# SkyWalking agent配置
export SW_AGENT_NAME=gateway-server
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为 300。
export JAVA_AGENT=‐javaagent:/usr/local/src/apache‐skywalking‐apm‐bin‐es7/agent/skywalking‐agent.jar
java $JAVA_AGENT ‐jar xxx.jar

2.6 Gateway接入微服务不显示问题

需将agent\optional-plugins目录下的gateway包移至agent/plugins目录。

在这里插入图片描述

项目中我是用的是gateway 2.0的版本,但是移入2.0的还是不显示,2.1的可以显示。

3. 自定义SkyWalking链路追踪

SkyWalking链路追踪的为请求接口,不会追踪接口下所涉及到的方法,为了方便排查问题,可做如下操作:

3.1 引入依赖

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <!--与下载的skywalking版本一致-->
    <version>8.6.0</version>
</dependency>

3.2 追踪方法

通过@Trace注解加在业务方法上可以将该方法在追踪面板中显示出来。

@Trace
public String hello() {
    
    
    return "hello";
}

通过@Tags或@Tag注解可以为追踪链路增加额外的信息。

@Tag注解中有两个属性,key为自定义名称,一般设置为方法名,value 可以是表示返回值的returnedObj或者表示参数的arg[参数索引]

示例:

①、@Tag-方法返回值示例

@Trace
@Tag(key = "hello",value = "returnedObj")
public String hello(Integer id) {
    
    
    return "hello world";
}

在这里插入图片描述

②、@Tags与@Tag-返回方法参数与方法返回值

@Trace
@Tags({
    
    @Tag(key = "helloParam",value = "arg[0]")
    ,@Tag(key = "helloReturn",value = "returnedObj")})
public String hello(Integer id) {
    
    
    return "hello world";
}

在这里插入图片描述

4. SkyWalking集成日志

4.1 logback配置

官方配置地址:https://github.com/apache/skywalking/blob/v8.6.0/docs/en/setup/service-agent/java-agent/Application-toolkit-logback-1.x.md

引入依赖:

<!--skywalking集成日志-->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.6.0</version>
</dependency>

logback-spring.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引入 Spring Boot 默认的 logback XML 配置文件  -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="console" 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>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
            </layout>
        </encoder>
    </appender>
    
	<!--Skywalking通过grpc上报日志--> 
    <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>

    <!-- 设置 Appender -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="grpc-log"/>
    </root>

</configuration>

项目启动后请求接口会生成带有“[TID:1a418fc3c3b94aa6949800cc67191854.136.16529817427060001]” TID的日志,可根据TID及追踪ID在前台UI中进行搜索。

在这里插入图片描述

注意:

当SkyWalking没有部署在本地时,需要将agent\config\agent.config文件添加如下配置:

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

其中:

配置名 解释 默认值
plugin.toolkit.log.transmit_formatted 是否以格式化或未格式化的格式传输记录的数据 true
plugin.toolkit.log.grpc.reporter.server_host 指定要向其报告日志数据的grpc服务器的主机 127.0.0.1
plugin.toolkit.log.grpc.reporter.server_port 指定要向其报告日志数据的grpc服务器的端口 11800
plugin.toolkit.log.grpc.reporter.max_message_s ize 指定grpc客户端要报告的日志数据的最大大小 10485760
plugin.toolkit.log.grpc.reporter.upstream_time out 客户端向上游发送数据时将超时多长时间 单位是秒 30

4.2 log4j 配置

官方配置地址:https://skywalking.apache.org/docs/main/v8.6.0/en/setup/service-agent/java-agent/application-toolkit-log4j-1.x/

4.2 log4j2j 配置

官方配置地址:https://skywalking.apache.org/docs/main/v8.6.0/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x/

5. SkyWalking告警功能

官方文档:https://github.com/apache/skywalking/blob/v8.6.0/docs/en/setup/backend/backend-alarm.md

告警规则都定义在config/alarm-setting.yml中。报警规则定义分为三个部分:

  1. 报警规则:它们定义了应如何触发指标警报以及应考虑哪些条件。
  2. 网络钩子(Webhook):Web 服务终结点的列表,应在触发警报后调用。
  3. gRPCHook:远程 gRPC 方法的主机和端口,应在触发警报后调用。

5.1 默认报警规则

为了方便起见,我们在版本中提供了默认值。它包括以下规则:

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

5.2 网络钩子

可以理解为Web层面的回调机制,当触发报警时,SkyWalking的告警消息会通过HTTP请求进行发送,请求方式为POST,Content-Type 为 application/json,其JSON 数据实基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>进行序列化的,JSON数据示例:

[{
    
    
	"scopeId": 1, 
	"scope": "SERVICE",
	"name": "serviceA", 
	"id0": "12",  
	"id1": "",  
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "alarmMessage xxxx",
	"startTime": 1560524171000,
    "tags": [{
    
    
        "key": "level",
        "value": "WARNING"
     }]
}, {
    
    
	"scopeId": 1,
	"scope": "SERVICE",
	"name": "serviceB",
	"id0": "23",
	"id1": "",
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "alarmMessage yyy",
	"startTime": 1560524171000,
    "tags": [{
    
    
        "key": "level",
        "value": "CRITICAL"
    }]
}]
  • scopeIdscope:所有作用域都在 中定义。org.apache.skywalking.oap.server.core.source.DefaultScopeDefine
  • name:目标 scope 的实体名称。请遵循实体名称定义
  • id0:与名称匹配的 scope 的 ID。使用关系范围时,它是源实体 ID。
  • id1:使用关系作用域时,它是目标实体 ID。否则,它是空的。
  • ruleName::在alarm-settings.yml中配置的规则名称。
  • alarmMessage:警报文本消息。
  • startTime:告警时间,格式为时间戳。
  • tags:在alarm-settings.yml中配置的标记。

5.3 告警功能实现

创建网络钩子所需实体类:

@Data
public class SkyWalkingAlarm {
    
    
    private Integer scopeId;
    private String scope;
    private String name;
    private String id0;
    private String id1;
    private String ruleName;
    private String alarmMessage;
    private Long startTime;
}

SkyWalking回调接口,需要在config/alarm-setting.yml中结尾添加回调路径:

webhooks:
  - http://127.0.0.1:8800/test/alarm

然后为该请求实现业务:

@RestController
@RequestMapping("/test")
@Slf4j
public class SkyWalkingController {
    
    

    @PostMapping("/alarm")
    public String alarm(@RequestBody List<SkyWalkingAlarm> alarmList) {
    
    
        log.info("=====告警信息提醒=====");

        StringBuilder sb = new StringBuilder();

        for (SkyWalkingAlarm alarm : alarmList) {
    
    
            sb.append("scopeId: ").append(alarm.getScopeId())
            .append("\nscope: ").append(alarm.getScope())
            .append("\n目标 Scope 的实体名称: ").append(alarm.getName())
            .append("\nScope 实体的 ID: ").append(alarm.getId0())
            .append("\nid1: ").append(alarm.getId1())
            .append("\n告警规则名称: ").append(alarm.getRuleName())
            .append("\n告警消息内容: ").append(alarm.getAlarmMessage())
            .append("\n告警时间: ").append(alarm.getStartTime())
            .append("\n\n‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐\n\n");
        }
        System.out.println(sb);

        return "告警信息提醒";
    }
}

猜你喜欢

转载自blog.csdn.net/xiaochen_2715/article/details/125431725