SpringCloud Alibaba微服务实战之Skywalking链路追踪

SpringCloud Alibaba微服务实战之Skywalking链路追踪

大家好,我是一安~

导读:在上一篇文章中我们讲解了如何整合logback日志框架,今天继续讲解如何整合sky-walking实现链路追踪。

简介

在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。

Spring Cloud Sleuth提供了一套完整的服务跟踪的解决方案,在分布式系统中提供追踪解决方案并且兼容支持了zipkinSpringCloud Alibaba微服务实战之Skywalking链路追踪本文重点不是讲Spring Cloud Sleuth,这里简单提一下如何使用:

SpringCloudF版起已不需要自己构建Zipkin Server了,只需调用jar包即可java -jar zipkin-server-2.12.9-exec.jar,运行控制台:http://localhost:9411/zipkin/

完整的调用链路:一条链路通过Trace Id唯一标识,Span标识发起的请求信息,各span通过parent id关联起来SpringCloud Alibaba微服务实战之Skywalking链路追踪

引入依赖:

<!--包含了sleuth+zipkin-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

修改配置:

zipkin:
  base-url: http://localhost:9411
sleuth:
  sampler:
    #采样率值介于 0 到 1 之间,1 则表示全部采集
    probability: 1

通过以上步骤,就可以实现Spring Cloud的链路追踪,Sleuth会自动为每个请求生成唯一的跟踪ID,而Zipkin会将这些跟踪ID聚合在一起,以形成完整的链路追踪。

正文SkyWalking

介绍

SkyWalking是一个开源的应用程序性能管理(APM)系统,旨在提供分布式跟踪、度量、日志和诊断解决方案,以帮助开发人员更好地理解和优化应用程序性能。

SkyWalking支持多种编程语言和框架,包括Java、.NET、Node.js、PHP、Python、Golang、Spring、Dubbo、gRPC等。它可以跟踪分布式应用程序中的请求流,收集应用程序的度量数据和日志,并提供可视化的仪表板和警报功能,以帮助开发人员快速发现和解决性能问题。

SkyWalking是由Apache Software Foundation孵化的项目,它采用了分布式架构和插件化设计,可以轻松地与其他系统集成,如ELK、Prometheus、Zipkin等。

SkyWalking数据存储支持:Elasticsearch、MySQL、H2、TiDB。默认是H2,而且是存到内存。实际我们一般将其存到ES

SkyWalking启动之后,会启动两个Java服务:Skywalking-Collector、Skywalking-Webapp

  • Skywalking-Collector:追踪信息收集器,通过gRPC/Http收集客户端的采集信息,gRPC默认端口 11800,Http默认端口 12800 。默认采用gRPC
  • Skywalking-Webapp:管理平台页面,默认端口 8080

Agent(客户端)收集数据并将其推送到后端,再对数据进一步分析,我们称之为“推送”模式。SkyWalking即使用了推送模式,同时也可进行数据拉取。在SkyWalking-8.x的版本中已经集成从Prometheus的服务中获取终端用户的数据。

SpringCloud Alibaba微服务实战之Skywalking链路追踪
  • agent:客户端需要指定的目录,其中有一个jar,就是负责和客户端整合收集日志
  • bin:服务端启动的脚本
  • config:一些配置文件的目录
  • logsoap服务的日志目录
  • oap-libsoap所需的依赖目录
  • webappUI服务的目录

官网:https://skywalking.apache.org/

下载链接:https://skywalking.apache.org/downloads/

历史下载链接:https://archive.apache.org/dist/skywalking/

小编下载的是:apache-skywalking-apm-es7-8.7.0版本

修改配置

/config/application.yml

  • 修改默认注册中心选择nacosSpringCloud Alibaba微服务实战之Skywalking链路追踪
  • 数据存储选择ESSpringCloud Alibaba微服务实战之Skywalking链路追踪

webapp/webapp.yml

  • UI服务的端口,默认8080SpringCloud Alibaba微服务实战之Skywalking链路追踪

启动

启动命令在bin目录下,这里需要启动两个服务,如下:

  • oap服务:对应的启动脚本oapService.batLinux下对应的后缀是sh
  • UI服务:对应的启动脚本webappService.batLinux下对应的后缀是sh

当然还有一个startup.bat/startup.sh启动文件,可以直接启动上述两个服务,我们可以直接使用这个脚本,直接双击,将会弹出两个窗口则表示启动成功。SpringCloud Alibaba微服务实战之Skywalking链路追踪

访问http://localhost:9999/SpringCloud Alibaba微服务实战之Skywalking链路追踪访问http://localhost:9200/SpringCloud Alibaba微服务实战之Skywalking链路追踪

微服务引入

想要传输数据必须借助skywalking提供的agent,只需要在启动参数指定即可,命令如下:

-javaagent:D:localspringcloudapache-skywalking-apm-bin-es7agentskywalking-agent.jar
-Dskywalking.agent.service_name=account-service
-Dskywalking.collector.backend_service=localhost:11800

命令解析如下:

-javaagent:指定skywalking中的agent中的skywalking-agent.jar的路径
-Dskywalking.agent.service_name:指定在skywalking中的服务名称,一般是微服务的spring.application.name
-Dskywalking.collector.backend_service:指定oap服务绑定的地址,并且oap服务默认的端口是11800,因此只需要配置为127.0.0.1:11800

idea添加vm参数:SpringCloud Alibaba微服务实战之Skywalking链路追踪启动微服务,并调用接口测试:

  • 仪表盘SpringCloud Alibaba微服务实战之Skywalking链路追踪SpringCloud Alibaba微服务实战之Skywalking链路追踪
  • 拓扑图SpringCloud Alibaba微服务实战之Skywalking链路追踪
  • 追踪SpringCloud Alibaba微服务实战之Skywalking链路追踪

性能剖析

新建任务(端点可从追踪页面获取):SpringCloud Alibaba微服务实战之Skywalking链路追踪代码休眠5s:

  @Override
  public Account selectByCode(String accountCode) {
      LambdaQueryWrapper<Account> wrapper = new LambdaQueryWrapper<>();
      wrapper.eq(Account::getAccountCode,accountCode);
      try {
          TimeUnit.SECONDS.sleep(5);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
      Account account = baseMapper.selectOne(wrapper);
      return account;
  }

点击分析,可以看到详细的堆栈信息:SpringCloud Alibaba微服务实战之Skywalking链路追踪下滑可以明确定位到哪一行:SpringCloud Alibaba微服务实战之Skywalking链路追踪

日志监控

大家在UI端应该看到一个日志的模块,用于收集客户端的日志,默认是没有数据的,那么需要如何将日志数据传输到skywalking中呢?

日志框架的种类很多,比较出名的有log4j,logback,log4j2,小编这里直接使用上篇集成好的logback

引入依赖:

<!-- 该引用用于logback获取tranceId,也就是tid -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.7.0</version>
</dependency>
 
<!-- 该引用用于代码获取tranceId -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.7.0</version>
</dependency>

修改logback-spring.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <springProperty scope="context" name="logpath" source="yian.logs.path" defaultValue="/org/yian/logs"/>
    <springProperty scope="context" name="ftst" source="yian.logs.ftst" defaultValue="0101"/>
    <substitutionProperty name="LOG_HOME" value="${logpath}"/>
    <substitutionProperty name="FTST" value="${ftst}"/>
    <substitutionProperty name="LOG_HOME_COMMON" value="${LOG_HOME}/stdout"/>
    <substitutionProperty name="LOG_HOME_ERROR" value="${LOG_HOME}/error"/>
    <!--输出操作日志-->
    <substitutionProperty name="LOG_HOME_PERFORMANCE" value="${LOG_HOME}/common"/>

    <!--日志传输到skywalking的appender-->
    <appender name="skywalkingLog" 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>${FTST}|%d{yyyy-MM-dd' 'HH:mm:ss.sss}|%-5level|%thread|${springAppName:-},%tid,%logger{36} - %msg%n</pattern>
            </layout>
        </encoder>
    </appender>

    <!-- console -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <!-- 格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度  %msg:日志消息,%n是换行符-->
                ${FTST}|%d{yyyy-MM-dd' 'HH:mm:ss.sss}|%-5level|%thread|${springAppName:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%logger{36} - %msg%n
            </pattern>
        </layout>
    </appender>

    <!-- file common -->
    <appender name="fileCommonLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_COMMON}-%d{yyyy-MM-dd}-%i.txt</fileNamePattern>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>100MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>
                    ${FTST}|%d{yyyy-MM-dd' 'HH:mm:ss.sss}|%-5level|%thread|${springAppName:-},%tid,%logger{36} - %msg%n
                </pattern>
            </layout>
        </encoder>
    </appender>

    <!-- file error -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_ERROR}-%d{yyyy-MM-dd}-%i.txt</fileNamePattern>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>100MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>
                    ${FTST}|%d{yyyy-MM-dd' 'HH:mm:ss.sss}|%-5level|%thread|${springAppName:-},%tid,%logger{36} - %msg%n
                </pattern>
            </layout>
        </encoder>
    </appender>

    <!-- file performance -->
    <appender name="filePerformanceLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_PERFORMANCE}-%d{yyyy-MM-dd}-%i.txt</fileNamePattern>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>100MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>
                %msg%n
            </pattern>
        </encoder>
    </appender>

    <!--操作日志日志配置输入性能日志文件-->
    <logger name="org.yian.log.SysLogAspect" level="DEBUG" additivity="false">
        <appender-ref ref="filePerformanceLog"/>
    </logger>

    <root level="info">
        <appender-ref ref="skywalkingLog" />
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileCommonLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>

重启服务,并请求测试接口:SpringCloud Alibaba微服务实战之Skywalking链路追踪SpringCloud Alibaba微服务实战之Skywalking链路追踪

至此我们已通过sky-walking实现链路追踪。


如果这篇文章对你有所帮助,或者有所启发的话,帮忙 分享、收藏、点赞、在看,你的支持就是我坚持下去的最大动力!

SpringCloud Alibaba微服务实战之Skywalking链路追踪

springboot集成redis采用分布式锁实现接口限流


Redis缓存失效问题:缓存穿透-缓存雪崩-缓存击穿


为了偷懒,自己封装了一个自适配的数据单位转换工具类

SpringCloud Alibaba微服务实战之Skywalking链路追踪

原文始发于微信公众号(一安未来):SpringCloud Alibaba微服务实战之Skywalking链路追踪

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/145069.html

(2)
青莲明月的头像青莲明月

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!