一文上手skywalking【下】

一、skywalking agent

1.1 skywalking agent探针

探针表示集成到目标系统中的代理或 SDK 库,即收集并格式化数据, 并发送到后端 包括链路追踪和性能指标.

通过地址: Downloads | Apache SkyWalking 可以下载得到你所需要的各个版本.这里选择 Java 9.1.0版本.

1.2 skywalking java agent目录

下载完成之后,直接解压即可,解压完成之后的目录结构如下图所示:

  • logs:skywalking agent的相关运行日志

  • bootstrap-plugins:插件包

  • optional-plugins:插件包(可供选择的插件包,如果需要生效则需要拷贝到plugins包下)

  • plugins:插件包(生效的插件包,支持多个框架链路追踪)

  • optional-reporter-plugins:插件包

  • activations:插件包

  • config: 配置文件

  • skywalking-agent.jar:agent代理的jar包【主要是使用这个jar包】

1.3 skywalking 配置姿势

当项目开发完毕之后,可以通过java -jar进行部署,此时可以添加如下的参数,对skywalking agent进行配置.

配置姿势一:

bash 复制代码
-javaagent:../skywalking-agent.jar=agent.service_name=app名称,collector.backend_service=127.0.0.1:11800

配置姿势二:

bash 复制代码
-javaagent: ../skywalking-agent.jar -Dskywalking.agent.service_name=应用名称 -Dskywalking.collector.backend_service=127.0.0.1:11800
  • agent.service_name:客户端服务名,在apm系统中显示的服务名称

  • collector.backend_service:skywalking上传数据的服务地址

  • 优先级从高到低依次是:

    • JVM配置

    • 环境变量配置

    • agent.config 【最低】

windows下配置示例:

  • skywalking java agent解压目录,假设放到桌面,如下所示:

此时可以按照如下的方式进行配置,注意路径写法:

bash 复制代码
-javaagent:C:\Users\rj\Desktop\skywalking-agent\skywalking-agent.jar -Dskywalking.agent.service_name=SkyWalkingApp -Dskywalking.collector.backend_service=0.0.0.0:11800

以上的方式都是打包之后,部署的时候,指定skywalking java agent,我们也可以在idea当中进行配置.

【重要说明】: 搭建一个简单的spring boot工程,进行简单的服务调用即可.假设这一步你已经完成.

选择【Add VM options】

配置成功

注意事项:

  • agent.service_name:客户端服务名,在apm系统中显示的服务名称,可以自己指定一个

  • collector.backend_service: SkyWalking上传数据的的服务地址, 也就是安装了OAP-server的服务器的ip地址或者域名.

二、skywalking使用实操

2.1 基本使用

配置好skywalking agent之后,直接启动项目,猛烈的请求几次,观察skywalking ui数据变化.

global面板展示:

service面板展示:

Instance面板展示:

EndPoint面板展示:

拓扑图:

链路追踪:

链路追踪页面和拓扑图页面根据服务及调用关系的不同,展示的是不一样的,具体取决于你的项目.通过上边的图可以发现,整个skywalking可以正常的、有效的工作了.

2.2 自定义链路追踪配置

  • 我们可以针对具体的业务方法进行细粒度的链路追踪.

  • 默认的追踪方式只能追踪具体的服务与数据库相关的链路,对于一个服务内的业务方法我们可以自己定义追踪.

理解一下TraceID和Span Id:

  • TraceID用来标记一条记录链路,一条请求链路中包含一个Trace ID,多个Span ID,如下图所示:

我们可以对项目当中的某个业务进行【链路追踪】,方便问题的排查, 例如,在生产环境当中,请求某个接口较慢, 我们就可以根据自定义的链路追踪进行排查问题.

按照三层结构, controller -> service调用关系,记录当前业务当中的方法,将这些方法加入到链路当中,记录入参、出参等.

在刚才工程的当中或者新建一个普通的spring boot工程,三层结构走起, 引入如下依赖即可:

XML 复制代码
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.12.0</version>
</dependency>
java 复制代码
    @GetMapping("/track")
    public String track(){
        userService.m1();
        return "自定义链路追踪!";
    }

service层代码,这里需要注意的是,此处代码没有任何实际意义,只是演示自定义链路追踪而已.

java 复制代码
@Service
public class UserService {

    @Trace
    public void m1(){
        System.out.println("m1 method");
        m2();
    }

    @Trace
    public void m2(){
        System.out.println("m2 method");
        m3();
    }

    @Trace
    public void m3(){
        System.out.println("m3 method");
    }
}

在idea当中配置好skywalking java agent,启动项目,观察skywalking ui上的数据变化.

记录方法的入参及出参:

java 复制代码
@Tags({
    @Tag(key = "hello-input", value = "arg[0]"),
    @Tag(key = "hello-output", value = "returnedObj")
})

在需要追踪的方法上,添加注解,注意事项如下所示:

  • 不要导错包了
java 复制代码
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
  • 参数含义:
    • value="arg[0]"表示方法的入参,arg[0]表示入参第一个参数,如果有第二个,则直接写arg[1],依次类推,如果业务方法没有入参,则可以省略不写.

    • value = "returnedObj"表示方法出参,returnedObj为固定写法,表示出参.

    • 如果入参、出参为对象 ,则实体类对象必须要重写toString方法

java 复制代码
    // service
    @Trace
    @Tags({
            @Tag(key = "m4-input", value = "arg[0]"),
            @Tag(key = "m4-output", value = "returnedObj")
    })
    public String m4(String s){
        System.out.println("m4 method");
        return "记录方法入参、出参!" + s;
    }
    
    // controller
    @GetMapping("/m4")
    public String m4(@RequestParam("s") String s){
        return userService.m4(s);
    }

猛烈请求接口,查看skywalking ui当中的【追踪】,找到请求的接口,具体操作如下所示:

2.3 性能剖析模块

操作步骤:

  • 新建任务: 填入需要分析的端点

  • 对任务进行采样

  • 查看链路信息

  • 性能分析: 查看对应方法的调用栈、找出可能会出问题的地方

  • 一个服务在监控续续时间内只能设置一个端口监控任务

新建【性能分析】:

新建任务界面:

java 复制代码
     /**
     * 性能监控
     * 测试service
     */
    public void m5(){
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("m45 method");
    }



    // 测试controller
    @GetMapping("/m5")
    public String m5(){
        userService.m5();
        return "性能监控!";
    }

然后猛烈的请求接口,观察【性能剖析】页面

分析结果

注意事项:

  • 性能剖析的接口,调用过程一定不能太快,【尤其测试的时候, 最好在业务方法当中Thread.sleep()一下】,如果接口,调用太快,则skywalking 无法采样,造成没有结果.

2.4 日志和rpc数据上报

应用场景:

  • 用户请求接口,怎么在我们日志中找到traceId来跟踪系统调用链路

  • 需要在系统日志打印出traceId

操作步骤:

  • 引入依赖
  • 配置logback
XML 复制代码
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.12.0</version>
</dependency>

配置logback打印日志(SpringBoot默认使用Logback),配置文件名 logback.xml

编写logback.xml文件, 将当前输出的日志输出到控制台当中.配置内容如下所示:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志输出格式 -->
    <property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] %green(%-5level) [%thread] %yellow([%tid]) %cyan(%logger{50}) : %msg%n" />
    <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>${FILE_LOG_PATTERN}</Pattern>
            </layout>
        </encoder>
    </appender>
    <!-- 异步输出 控制台 -->
    <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <appender-ref ref="STDOUT"/>
    </appender>

    <root level="info">
        <appender-ref ref="ASYNC_STDOUT"/>
    </root>
</configuration>

在需要的地方打印日志.如下所示:

java 复制代码
  private Logger logger = org.slf4j.LoggerFactory.getLogger(UserService.class);

  public void m5(){
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        // System.out.println("m45 method");
        logger.info("hello m5");
   }

然后,猛烈的请求接口,在idea控制台查看结果.如下所示:

RPC数据上报:

如果要将数据上报到oap上,则需要修改skywalking-agent的配置文件,具体操作如下所示:

在配置文件末尾添加:

bash 复制代码
# 指定要向其报告日志数据的GRPC服务器主机
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:你的ip地址}
# 指定要向其报告日志数据的GRPC服务器端口
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
# 指定GRPC客户端要报告的日志数据的最大大小
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}

修改日志文件logback.xml文件,添加如下内容:

XML 复制代码
<!-- 使用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.TraceIdPatternLogbackLayout">
            <Pattern>${FILE_LOG_PATTERN}</Pattern>
        </layout>
    </encoder>
</appender>

<root level="info">
    <appender-ref ref="ASYNC_STDOUT"/>
    <appender-ref ref="GRPC_LOG"/>
</root>

完整的logback.xml文件如下所示:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志输出格式 -->
    <property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] %green(%-5level) [%thread] %yellow([%tid]) %cyan(%logger{50}) : %msg%n" />
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 配置了skywalking的traceId的日志打印的格式 -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <Pattern>${FILE_LOG_PATTERN}</Pattern>
            </layout>
        </encoder>
    </appender>
    <!-- 异步输出 控制台 -->
    <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <appender-ref ref="STDOUT"/>
    </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.TraceIdPatternLogbackLayout">
                <Pattern>${FILE_LOG_PATTERN}</Pattern>
            </layout>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="ASYNC_STDOUT"/>
        <appender-ref ref="GRPC_LOG"/>
    </root>
</configuration>

猛烈请求接口,查看skywalking ui的【日志模块】.

点击日志,查看相关日志的详情:

2.5 告警模块和webhook

  • 监控业务相关接口性能,超过阈值则触发告警功能

  • 通过调用**webhook接口进行触发,具体的webhook接口地址可以自行定义路径**

    • 注意:OAP Server的网络可以触发的webhook接口
  • 开发人员可以在webhook接口中编写告警方式,比如邮件、短信等,它本质上就是一个http接口而已.

  • Apache Skywalking**默认的告警规则配置**

    • 安装目录下的config文件夹下 alarm-settings.yml文件, 如果是docker容器,则进入到容器当中去找到相关的配置文件即可

    • 默认内置多个规则

      • 最近3分钟内服务的平均响应时间超过1秒

      • 最近2分钟服务成功率低于80%

      • 最近3分钟90%服务响应时间超过1秒

      • 最近2分钟内服务实例的平均响应时间超过1秒

在alarm-settings.yml当中,找到最下边,配置自己的接口.【特别注意】: 这个接口必须得能让skywalking能调用到.如果使用的是云服务器,则本地服务要么打包到云服务器上去,要么去折腾内网穿透去,总之,必须得能使skywalking服务器访问我们自己编写的接口.

alarm-settings.yml配置文件当中的一些重要的配置,这里的配置大部分不需要我们自己调整,如果要调整则需要根据自己的业务进行调整即可.

  • metrics-name: 脚本中的度量名称

  • threshold: 阈值

  • op: 比较操作符,可以设定>,<,=

  • period: 多久检查一次当前的指标数据是否符合告警规则,单位分钟

  • count: 达到多少次后,触发告警消息

  • silence-period: 在多久时间之内,忽略相同的告警消息,在时间T触发了某告警,那么在(T+10)这个时间段,不会再次触发相同告警

  • message: 告警消息内容

  • webhooks: 配置告警产生时的触发的调用地址

bash 复制代码
service_resp_time_rule(服务响应时间规则):
metrics-name: 指定要监控的指标名称为service_resp_time,表示服务的响应时间。
op: 操作符为 ">",表示当指标值大于后面的阈值时触发告警。
threshold: 阈值为 1000,即当服务响应时间大于 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.",其中{name}会被替换为具体的服务名称。

定义本地接口步骤:

  • 定义实体类,这个实体类由官方提供,不必更改.
  • 定义webhook接口
java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AlarmMessage {
    private int scopeId;
    private String scope;
    private String ruleName;
    private String name;
    private String id0;
    private String id1;
    private String alarmMessage;
    private long startTime;
}

编写webhooks接口:

java 复制代码
@RestController
public class AlertMessageController {
    private Logger logger = LoggerFactory.getLogger(AlertMessageController.class);

    private List<AlarmMessage> message = new ArrayList<>();

    @PostMapping("/webhooks")
    public void webhooks(@RequestBody List<AlarmMessage> messageList){
        logger.info("webhooks:{}", messageList);
        // todo: 收到消息之后,可以发送短信、邮件等其它业务处理.【结合自己的业务处理即可】
        message.addAll(messageList);
    }

    @GetMapping("/show")
    public List<AlarmMessage> getMessage(){
        return message;
    }

}

编写业务接口:

java 复制代码
    public void m5(){
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        // System.out.println("m45 method");
        logger.info("hello m5");
    }

这里的方法延迟2s钟执行,这样会触发告警信息.请求几次接口,等三分钟, 查看是否收到了webhooks;

结果查看:

  • 控制台输出
bash 复制代码
INFO  [XNIO-1 task-2] [TID:f78c724f54b143088784f307b5aec6a7.139.17270940166880001] com.rj.controller.AlertMessageController : webhooks:[AlarmMessage(scopeId=2, scope=SERVICE_INSTANCE, ruleName=service_instance_resp_time_rule, name=0d5ce315eb60407f819d5f800c0fa02f@192.168.200.56 of rj-skywalking-app, id0=cmotc2t5d2Fsa2luZy1hcHA=.1_MGQ1Y2UzMTVlYjYwNDA3ZjgxOWQ1ZjgwMGMwZmEwMmZAMTkyLjE2OC4yMDAuNTY=, id1=, alarmMessage=Response time of service instance 0d5ce315eb60407f819d5f800c0fa02f@192.168.200.56 of rj-skywalking-app is more than 1000ms in 2 minutes of last 10 minutes, startTime=1727094016588), AlarmMessage(scopeId=6, scope=ENDPOINT_RELATION, ruleName=endpoint_relation_resp_time_rule, name=User in User to GET:/m5 in rj-skywalking-app, id0=VXNlcg==.0_VXNlcg==, id1=cmotc2t5d2Fsa2luZy1hcHA=.1_R0VUOi9tNQ==, alarmMessage=Response time of endpoint relation User in User to GET:/m5 in rj-skywalking-app is more than 1000ms in 2 minutes of last 10 minutes, startTime=1727094016588)]
  • 告警模块输出信息:
  • 查看告警信息:

三、总结

本文主要介绍了skywalking 的一些基础概念及常用的操作,希望可以帮助到需要的同学.

全文完.

相关推荐
qq_174482857525 分钟前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
代码小鑫2 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖2 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
周全全3 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
飞升不如收破烂~4 小时前
Spring boot常用注解和作用
java·spring boot·后端
计算机毕设源码qq-38365310414 小时前
(附项目源码)Java开发语言,215 springboot 大学生爱心互助代购网站,计算机毕设程序开发+文案(LW+PPT)
java·开发语言·spring boot·mysql·课程设计
无尽的大道4 小时前
深入理解 Java 阻塞队列:使用场景、原理与性能优化
java·开发语言·性能优化
loey_ln4 小时前
webpack配置和打包性能优化
前端·webpack·性能优化
岁岁岁平安4 小时前
springboot实战(15)(注解@JsonFormat(pattern=“?“)、@JsonIgnore)
java·spring boot·后端·idea
潜洋8 小时前
Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序
java·spring boot·后端