分布式链路追踪Skywalking

发布时间 2023-06-21 16:32:31作者: 吴磊的

简介

  skywalkings是2015年开源的一款国产框架,2017年的时候加入了Apache孵化器。skywalking是分布式应用程序的性能监控工具,具有多种监控手段,作为APM工具,它具有分布式追踪、性能指标分析、应用和服务依赖分析等功能。可以通过语言探针来获取监控数据。专门是为了微服务(spring cloud)、云原生架构与容器架构(docker/k8s)而设计的。

  Skywalking整体架构一共分四块:

    Skywalking-Agent(项目引入,Skywalking-Agent 收集应用程序链路信息,交给Skywalking-OAP处理器)
    Skywalking-OAP-Server 把 Skywalking-Agent 发过来的 Tracing 数据交给 Analysis Core 分析,最后将结果存储到外部存储器。
    数据存储(H2/mysql/ElasticSearch)
    Skywalking UI 负责给用户查看链路等信息

  

安装

1. 安装存储器es

1】创建好配置和数据目录,并配置所有端口都可以访问
[root@node1 wulei]# mkdir -p /usr/local/wulei/elasticsearch/config
[root@node1 wulei]# mkdir -p /usr/local/wulei/elasticsearch/data
[root@node1 wulei]# echo "http.host: 0.0.0.0" > /usr/local/wulei/elasticsearch/config/elasticsearch.yml
[root@node1 wulei]# chmod -R 777 /usr/local/wulei/elasticsearch/

【2】下载并启动 9200是我们rest请求端口,9300是集群交互端口
docker run --name wl-es -p 9200:9200 -p 9300:9300 --privileged=true -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m -Xms512m" -v /usr/local/wulei/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /usr/local/wulei/elasticsearch/data:/usr/share/elasticsearch/data -v /usr/local/wulei/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.16.1

查看es首页 http://192.168.200.100:9200/

2. 安装oap

docker run --name wl-oap --restart always -d \
-e TZ=Asia/Shanghai -p 12800:12800 -p 11800:11800 \
--link wl-es -e SW_STORAGE=elasticsearch7 \
-e SW_STORAGE_ES_CLUSTER_NODES=wl-es:9200 \
apache/skywalking-oap-server:8.5.0-es7

参数:
--link <name or id>:alias ,添加到另一个容器的链接,可以添加别名或者不加
–link后面的参数和elasticsearch容器名⼀致;
SW_STORAGE=elasticsearch7 是固定的,使用es7;
SW_STORAGE_ES_CLUSTER_NODES:wl_es7也可改为es服务器部署的Ip地址,比如ip:9200

3. 安装ui界面

docker run -d --name wl-skywalking-ui \
--restart=always \
-e TZ=Asia/Shanghai \
-p 8080:8080 \
--link wl-oap \
-e SW_OAP_ADDRESS=wl-oap:12800 \
apache/skywalking-ui:8.5.0

  SkyWalking UI界面访问地址 ip:8080
  这时候看es索引,会发现有很多 SkyWalking 的索引了
  http://192.168.200.100:9200/_cat/indices?v=true&pretty。    sw开头的都是。

仪表盘

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

2. 展示栏(Global全局维度)
    Global、Service、Instance、Endpoint不同展示面板
    Services load:服务每分钟请求数
    Slow Services:慢响应服务,单位ms
    Un-Health services(Apdex): Apdex性能指标,1为满分
    Slow Endpoint:慢响应端点,单位ms
    Global Response Latency:百分比响应延时,不同百分比的延时时间,单位ms
    Global Heatmap:服务响应时间热力分布图,根据时间段内不同响应时间的数量显示颜色深度;
    底部栏:展示数据的时间区间,点击可以调整

3. 展示栏(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:每个服务实例的每分钟请求数

4. 展示栏(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线程数

5. 展示栏(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:当前端点每个时间段的请求成功率

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

 

Agent

1. 下载 https://skywalking.apache.org/downloads/。(如下图,解压后整个文件夹都需要用到,不能只复制 skywalking-agent.jar ,它会依赖到其他包)

2. 指定运行参数

-javaagent:C:\Users\Administrator\Desktop\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=Shop_Service
-Dskywalking.collector.backend_service=192.168.200.100:11800

3. 此时启动项目后先访问接口,再刷新下 skywalking 就能看到我们的面板信息了。

查看效果

  我们通过探针的形式收集数据,能看到服务的整体监控信息,响应统计、接口耗时、gc信息、执行的sql语句。但它只能看到服务与服务之间的链路信息(上游节点1 —> 本节点 —> 下游节点1。想要整个链路都能看到,那就整个链路都用探针监听就好了),看不到服务内部具体的信息(服务内部方法a调用方法b),看内部信息我们需要接入链路追踪的方式。

链路追踪

<!-- skywalking链路追踪 -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.5.0</version>
</dependency>
        
        
/**
 * @Tag(key = "方法名-input", value = "arg[0]"),arg[0] 表示第一个参数
 * @Tag(key = "方法名-output", value = "returnedObj"),returnedObj 是固定写法
 */
@Trace
@Tags(
        {
            @Tag(key = "test1-input", value = "arg[0]"),
            @Tag(key = "test1-output", value = "returnedObj")
        }
)
@Override
public List<Area> test1(Long parentId) {
    List<Area> areas = listByPId(parentId);
    test2();
    return areas;
}
方法加上 @Trace 注解后,就会把该方法(仅仅是该方法)加入链路监控了,再叠加一个 @Tags 后则能看到该方法的出参入参。如果某方法仅仅只加@Tags、由于不在链路上,所以是看不到参数的。

性能分析

新建任务:同一个服务在监听的时间段内,只能监听一个接口,该服务无法创建多个监听任务。

 进行分析

日志上报

1. 指定 skywalking oap 地址。修改  apache-skywalking-apm-bin\agent\config\agent.config 文件,指定  日志数据的grpc 的ip、prot、日志文件最大大小、上传日志超时时间。

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.200.100}
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}

2. 添加日志依赖

        <!--链路追踪,上报日志不需要用到这个jar-->
<!--        <dependency>-->
<!--            <groupId>org.apache.skywalking</groupId>-->
<!--            <artifactId>apm-toolkit-trace</artifactId>-->
<!--            <version>8.5.0</version>-->
<!--        </dependency>-->
        <!--日志上报 skywalking8.4.0之后才支持-->
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-logback-1.x</artifactId>
            <version>8.5.0</version>
        </dependency>

3. 指定日志输出格式

    <!--控制台日志-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <charset>UTF-8</charset>
            <pattern>%date [%thread] [%file:%line] [%level %logger{0}] - %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 随意写一个 appender ,甚至可以不在下面的 <root>中引用他 。
         不写一个 TraceIdPatternLogbackLayout 的日志,启动时会报错找不到[tid],tid是在 TraceIdPatternLogbackLayout 类中定义好的。
         如果我们在上面的console中使用[tid]也会报错说找不到,所以通常我们直接用该appender做console就好了
         -->
    <appender name="wulei-test" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <charset>UTF-8</charset>
            <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>
    <!-- 上报到skywalking -->
    <appender name="skywalking" 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="${LOG_LEVEL}">
        <appender-ref ref="console" />
        <appender-ref ref="skywalking" />
    </root>
解释说明

最终的日志配置

    <!--控制台日志-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <charset>UTF-8</charset>
            <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>
    <!-- 上报到skywalking -->
    <appender name="skywalking" 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="${LOG_LEVEL}">
        <appender-ref ref="console" />
        <appender-ref ref="skywalking" />
    </root>

告警规则

  在  apache-skywalking-apm-bin\config\alarm-settings.yml  中内置了一些默认告警规则。配置讲解:

metrics-name 脚本中的度量名称
threshold 阈值
op 比较操作符,可以设定>,<,=
period 多久检查一次当前的指标数据是否符合告警规则,单位分钟
count 达到多少次后,触发告警消息
silence-period 在多久时间之内,忽略相同的告警消息,在时间T触发了某告警,那么在(T+ period )这个时间段,不会再次触发相同告警 message 告警消息内容 webhooks 配置告警产生时的触发的调用地址

  1. 编写告警规则,指定webhook地址,然后重启  skywalking-oap-server