SkyWalking-入门

1. 安装

1.1 前置安装ES

1
2
3
4
5
6
7
8
9
10
11
mkdir -p /home/dockerdata/elasticsearch/config
mkdir -p /home/dockerdata/elasticsearch/data
chmod 777 -R /home/dockerdata/elasticsearch
echo "http.host: 0.0.0.0" >> /home/dockerdata/elasticsearch/config/elasticsearch.yml

docker run -d --name elasticsearch --privileged=true -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
-v /dockerData/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /dockerData/elasticsearch/data:/usr/share/elasticsearch/data \
-v /dockerData/elasticsearch/plugins:/usr/share/elasticsearch/plugins elasticsearch:7.16.2

1.2 安装Skywalking-OAP-Server

1
2
3
4
5
6
docker run -d --name skywalking-oap-server -p 12800:12800 -p 11800:11800 \
--link elasticsearch \
-e TZ=Asia/Shanghai \
-e SW_STORAGE=elasticsearch7 \
-e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 \
apache/skywalking-oap-server:8.5.0-es7

1.3 安装Skywalking-UI

1
2
3
4
5
docker run -d --name skywalking-ui -p 8080:8080 \
--link skywalking-oap-server \
-e TZ=Asia/Shanghai \
-e SW_OAP_ADDRESS=skywalking-oap-server:12800 \
apache/skywalking-ui:8.5.0

1.4 Nginx代理11800RPC接口

  • 如果在客户端数据上报时访问不到oap服务,需要做代理转发,通过nginx rpc代理的方式实现
1
2
3
4
5
6
7
8
9
10
11
12
upstream grpcservers {
server 192.168.80.128:11800; # Skywalking OAP 后端 11800 地址
}

server {
listen 11800 http2;
server_name skywalking;

location / {
grpc_pass grpc://grpcservers;
}
}

2. SpringBoot集成

2.1 下载探针

以8.5.0版本为例

  • 解压

    image-20220611174525345

  • agent目录文件的介绍

    • activations:插件包
    • bootstrap-plugins:插件包
    • config: 配置文件
    • logs:skywalking agent的相关运行日志
    • optional-plugins:插件包(可供选择的插件包,如果需要生效则需要拷贝到plugins包下)
    • optional-reporter-plugins:插件包
    • plugins:插件包(生效的插件包,支持多个框架链路追踪)
    • skywalking-agent.jar:agent代理的jar包)
  • 优先级:JVM配置 > 环境变量配置 > agent.config

2.2 编写一个SpringBoot测试项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@GetMapping("/list")
public List<UserDO> getUsers() {
return userService.getUsers();
}

......

@Override
public List<UserDO> getUsers() {
return getRandomUsers();
}

private List<UserDO> getRandomUsers() {
Random random = new Random();
List<UserDO> result = new ArrayList<>();
for (int j = 0; j < 3; j++) {
int i = random.nextInt(500);
result.add(getUserDelayed(i));
}
return result;
}

private UserDO getUserDelayed(int id) {
Random random = new Random();
int i = random.nextInt(1000);
try {
Thread.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
return getById(id);
}

2.3 添加VM启动参数

1
-javaagent:D:\tool\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar -Dskywalking.agent.service_name=skywalking-learn -Dskywalking.collector.backend_service=192.168.80.128:11800

  • agent.service_name:客户端服务名,在apm系统中显示的服务名称
  • collector.backend_service:SW上传的服务地址

2.4 查看效果

3. UI和指标

3.1 概念

  • Service 服务,具体的服务,比如用户服务

  • Instance 实例,服务的实例,比如xxx节点上的服务,id@ip

  • Endpoint 端点,服务对外提供的接口,一个接口就是一个端点

  • Service Apdex 用户满意程度

    • 最大值就是 1, 是一个不断优化的方向
    • 分3个指标,T 值代表着用户对服务性能满意的响应时间界限,假如T是0.5秒
      • 满意:响应时间少于 T 秒钟; 0.5秒内
      • 容忍:响应时间 T~4T 秒; 0.5~2秒内
      • 失望:响应时间超过 4T 秒; 多于2秒
  • SLA

    • 服务等级协议,全称:service level agreement,为保障服务的性能和可用性

    • 9越多代表全年服务可用时间越长服务更可靠,停机时间越短

      1
      2
      3
      4
      5
      6
      7
      1年 = 365天 = 8760小时

      99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
      99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
      99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟

      全年停机5.26分钟才能99.999%,即5个9
  • CPM 全称 call per minutes,是吞吐量(Throughput)指标,每分钟请求调用的次数

  • RT Response Time 表示请求响应时间

  • Percent Response 百分位数统计

    • 表示采集样本中某些值的占比,SkyWalking 有 “p50、p75、p90、p95、p99” 一些列值, “p99:360” 表示 99% 请求的响应时间在360ms以内

3.2 SkyWalking UI

  • 顶部控制栏

    • 仪表盘:查看被监控服务的运行状态
    • 拓扑图:以拓扑图的方式展现服务的关系
    • 追踪:以接口的列表方式展现
    • 性能剖析:对端点进行采样分析
    • 日志:可查看服务日志
    • 告警:触发告警的告警列表,包括了服务的失败率,超时等待
  • Global:全局维度

    • Services load:服务每分钟请求数
    • Slow Services:慢响应服务,单位ms
    • Un-Health services(Apdex): Apdex性能指标,1为满分
    • Slow Endpoint:慢响应端点,单位ms
    • Global Response Latency:百分比响应延时,不同百分比的延时时间,单位ms
    • Global Heatmap:服务响应时间热力分布图,根据时间段内不同响应时间的数量显示颜色深度;
  • Service:服务维度

    • Service Apdex(数字):当前服务的评分

    • Service Apdex(折线图):不同时间的Apdex评分

    • Service Avg Response Times:平均响应延时,单位ms

    • Service Response Time Percentile:百分比响应延时

    • Successful Rate(数字):请求成功率

    • Successful Rate(折线图):不同时间的请求成功率

    • Servce Load(数字):每分钟请求数

    • Servce Load(折线图):不同时间的每分钟请求数

    • Servce Instances Load:每个服务实例的每分钟请求数

  • Instance:实例维度

    • 对于CPU、内存的监控,Promethus更好一点
    • Service instance load:当前实例的每分钟请求数
    • Service Instance Successful Rate:当前实例的请求成功率
    • Service Instance Latency:当前实例的响应延时
    • JVM CPU:jvm占用CPU的百分比
    • JVM Memory:JVM内存占用大小,单位m
    • JVM GC Time:JVM垃圾回收时间,包含YGC和OGC
    • JVM GC Count:JVM垃圾回收次数,包含YGC和OGC
    • JVM Thread Count:JVM线程数
    • 其他几个是.NET的,java无需关心
  • Endpoint:端点维度

    • Endpoint Load in Current Service:每个端点的每分钟请求数
    • Slow Endpoints in Current Service:每个端点的最慢请求时间,单位ms
    • Successful Rate in Current Service:每个端点的请求成功率
    • Endpoint Load:当前端点每个时间段的请求数据
    • Endpoint Avg Response Time:当前端点每个时间段的请求行响应时间
    • Endpoint Response Time Percentile:当前端点每个时间段的响应时间占比
    • Endpoint Successful Rate:当前端点每个时间段的请求成功率
  • 拓扑图

    • 服务间的关系和连接情况,可以从这里进去具体某个服务查看详情
  • 追踪

    • 左侧:接口列表,请求为红色表示异常,蓝色表示正常
    • 右侧:追踪列表,api的各个连接点按照端点的先后顺序和时间排序
  • 性能剖析

    • 右上角,新建任务:新建需要分析的端点
    • 左侧列表:对任务进行采样
    • 右侧:每个端点的链路信息

4. 日志

4.1 背景

  • 日志中找到traceId来跟踪系统调用链路
  • 需要在系统日志打印出traceId

4.2 代码实现

  • 添加依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.5.0</version>
    </dependency>
  • 添加logback.xml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>  
    <!-- 控制台输出 -->
    <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>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern>
    </layout>
    </encoder>
    </appender>

    <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} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern>
    </layout>
    </encoder>
    </appender>

    <!--系统操作日志-->
    <root level="INFO">  
    <appender-ref ref="console"/>
    <appender-ref ref="grpc-log"/>
    </root>
    </configuration>
  • skywaling agent 默认是上传到本地的oap,如果oap server地址不是本地,则需要单独配置oap server地址,agent文件夹里面config配置

    1
    2
    3
    4
    5
    6
    7
    8
    #日志数据的grpc服务器的主机
    plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.80.128}
    #日志数据的grpc服务器的端口
    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}
  • 打印日志,查看日志模块

5. 告警

5.1 启动通知

  • 在alarm-settings.yml配置文件中,添加通知接口

    1
    2
    webhooks:
    - http://192.168.80.1:8080/notify/
  • 编写代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @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 long startTime;
    private transient int period;
    private transient boolean onlyAsCondition;
    }


    @RestController
    public class AlarmController {

    @PostMapping("/notify")
    public void webhook(@RequestBody List<AlarmMessage> alarmMessageList){
    System.out.println("收到告警消息:" +alarmMessageList);
    }
    }

6. 自定义链路追踪

6.1 背景

  • 对业务代码进行链路追踪,方便排查问题
  • 比如,某个接口请求耗时慢,想对业务接口方法进行追踪
  • controller->service 方法,记录业务方法加入到链路中,记录入参、返回值等

6.2 TraceId

TraceId用来标识一条请求链路,一条请求链路中包含一个Trace ID,多个Span ID

6.3 实现

  • 添加依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.5.0</version>
    </dependency>
  • 在Service业务方法添加注解 @Trace

  • 记录入参和返回值

    1
    2
    3
    4
    @Tags(
    {@Tag(key = "reqParam", value = "arg[0]"),
    @Tag(key = "respData", value = "returnedObj")}
    )

6.4 性能分析

  • 在性能分析页面,选择新建的任务,点击分析
  • 点击service上的查看,可以查看到对应的出入参
  • 查看堆栈信息可以,看到具体哪行代码慢