一文上手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, [email protected] of rj-skywalking-app, id0=cmotc2t5d2Fsa2luZy1hcHA=.1_MGQ1Y2UzMTVlYjYwNDA3ZjgxOWQ1ZjgwMGMwZmEwMmZAMTkyLjE2OC4yMDAuNTY=, id1=, alarmMessage=Response time of service instance [email protected] 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 的一些基础概念及常用的操作,希望可以帮助到需要的同学.

全文完.

相关推荐
weixin_307779132 小时前
Azure Data Factory ETL设计与调度最佳实践
数据仓库·性能优化·云计算·azure·etl
李白的粉3 小时前
基于springboot的在线教育系统
java·spring boot·毕业设计·课程设计·在线教育系统·源代码
小马爱打代码3 小时前
SpringBoot原生实现分布式MapReduce计算
spring boot·分布式·mapreduce
iuyou️3 小时前
Spring Boot知识点详解
java·spring boot·后端
一弓虽4 小时前
SpringBoot 学习
java·spring boot·后端·学习
来自星星的猫教授5 小时前
spring,spring boot, spring cloud三者区别
spring boot·spring·spring cloud
程序猿--豪6 小时前
webpack详细打包配置,包含性能优化、资源处理...
前端·webpack·性能优化
乌夷7 小时前
使用spring boot vue 上传mp4转码为dash并播放
vue.js·spring boot·dash
Harbor Lau8 小时前
Linux常用中间件命令大全
linux·运维·中间件
A阳俊yi8 小时前
Spring Boot日志配置
java·spring boot·后端