skywalking实现分布式系统链路追踪

作者: huan1993 | 来源:发表于2020-07-07 19:46 被阅读0次

    一、背景

        随着微服务的越来越流行,我们服务之间的调用关系就显得越来越复杂,我们急需一个APM工具来分析系统中存在的各种性能指标问题以及调用关系。目前主流的APM工具有CATZipkinPinpoint以及SkyWalking,本文主要简单介绍一下SkyWalking的搭建。

    二、SkyWalking的组成

    SkyWalking主要的几个组成模块。
    1、Agent 主要负责从系统中采集各种指标,链路数据,发送给 oap服务。
    2、oap服务接收Agent发送过来的数据,存储,执行分析,提供查询和报警功能。
    3、StorageUI负责存储数据以及查看数据。

    三、使用 docker-compose 搭建一个 oap 和 ui 服务

    version: '3'
    services:
      elasticsearch7:
        image: docker.elastic.co/elasticsearch/elasticsearch:7.5.0
        container_name: elasticsearch7
        restart: always
        ports:
          - 9023:9200
        environment:
          - discovery.type=single-node
          - bootstrap.memory_lock=true
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
          - TZ=Asia/Shanghai
        ulimits:
          memlock:
            soft: -1
            hard: -1
        networks:
          - skywalking
        volumes:
          - elasticsearch7:/usr/share/elasticsearch/data
      oap:
        image: apache/skywalking-oap-server:8.0.1-es7
        container_name: oap
        depends_on:
          - elasticsearch7
        links:
          - elasticsearch7
        restart: always
        ports:
          - 9022:11800
          - 9021:12800
        networks:
          - skywalking
        volumes:
          - ./ext-config:/skywalking/ext-config
      ui:
        image: apache/skywalking-ui:8.0.1
        container_name: ui
        depends_on:
          - oap
        links:
          - oap
        restart: always
        ports:
          - 9020:8080
        environment:
          SW_OAP_ADDRESS: oap:12800
        networks:
          - skywalking
    
    networks:
      skywalking:
        driver: bridge
    
    volumes:
      elasticsearch7:
        driver: local
    

    1、docker-compose文件的目录

    skywalking
    ├── ext-config
    │   └── application.yml
    ├── ext-libs
    ├── skywalking.yml
    └── temp.txt
    

    2、访问

    http://localhost:9020

    3、注意事项

    1、如果我们想覆盖oap镜像中的/skywalking/config 目录下的配置文件,我们可以在 docker 中挂载一个/skywalking/ext-config目录,将配置文件丢到此目录中即可。
    2、如果我们想覆盖oap镜像中的/skywalking/oap-libs 目录下的jar,我们可以在 docker 中挂载一个/skywalking/ext-libs目录,将新的jar包丢到此目录中即可,但是已经存在的jar包无法被覆盖。
    3、使用的版本是 8.0.1,数据持久化到 es7

    四、全局日志追踪 traceId 的使用

    方案一:

    1、引入依赖

    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-logback-1.x</artifactId>
        <version>8.0.1</version>
    </dependency>
    

    2、修改 logback.xml 文件

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Logback Configuration.  -->
    <configuration debug="false">
    
        <!-- ConsoleAppender:把日志输出到控制台 -->
        <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.mdc.TraceIdMDCPatternLogbackLayout">
                    <Pattern><![CDATA[
    %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} [%X{tid}] %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
                ]]></Pattern>
                </layout>
            </encoder>
        </appender>
    
        <root level="INFO">
            <appender-ref ref="STDOUT"/>
        </root>
    </configuration>
    
    

    方案二

    参考如下链接 https://github.com/apache/skywalking/blob/master/docs/en/setup/service-agent/java-agent/Application-toolkit-trace.md

    五、idea 或 jar 中使用

    使用如下命令,需要折成一行
    java 
    -javaagent:(agentjar包的位置)(eg: /Users/huan/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar )
    -Dskywalking.agent.service_name=xxxxx-service 
    -Dskywalking.collector.backend_service=127.0.0.1:9022  -jar xxxx.jar
    

    -javaagent 指定 agent jar 包的位置
    -Dskywalking.agent.service_name 指定服务名
    -Dskywalking.collector.backend_service 指定 oap 服务的地址

    idea中使用

    六、skywalking的目录解释

    apache-skywalking-apm-bin-es7
    ├── LICENSE
    ├── NOTICE
    ├── README.txt
    ├── agent
                            ├── activations
                          ├── bootstrap-plugins
                          ├── config   -- agent 的配置文件,比如我们上一步使用 -Dskywalking.agent.service_name配置的这些
                          ├── logs
                          ├── optional-plugins     可选插件      (将optional-plugins目录的jar包放到 plugins 目录下即可启动这些插件)
                          ├── plugins                     启用的插件
                         └── skywalking-agent.jar  我们自己的服务需要使用 -javaagent 指定到这个jar的位置
    ├── bin          oap/ui 的启动脚本
    ├── config    配置文件
    ├── licenses
    ├── oap-libs
    ├── tools
    └── webapp   ui界面
    

    七、访问 skywalking 的界面

    skywalking.jpg

    八、实战

    1、忽略某些url不被追踪

    1、第一步将 apm-trace-ignore-plugin-8.0.1.jar 从optional-plugins 移动到 plugins 目录中

    引入忽略url插件

    2、配置忽略url

    方法一:agent/config 目录下创建 apm-trace-ignore-plugin.config文件

    trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:需要忽略的url}
    eg:trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/xxx/**}
    

    方法二: 直接使用环境变量
    -Dskywalking.trace.ignore_path=需要忽略的url路径

    注意:
    1、忽略路径是支持 ant 风格的。
    2、忽略多个url使用英文的逗号分隔。

    2、追踪子线程的信息

    1、引入依赖

    <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.0.1</version>
    </dependency>
    

    2、使用@TraceCrossThread注解或使用SupplierWrapper/RunnableWrapper/TraceCrossThread

    @GetMapping("tractThread")
        public String tractThread() {
            log.info("准备自己线程信息");
            new Thread(RunnableWrapper.of(() -> log.info("子线程的信息"))).start();
            return "trace thread";
        }
    

    此处演示RunnableWrapper.of包装Runnable线程。

    追踪子线程

    3、如果某个方法SkyWalking没有追踪,但是想追踪并输出一些额外的tag信息等

    1、引入依赖

    <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.0.1</version>
    </dependency>
    

    2、自己想加入的方法使用 @Trace 注解修饰

    @GetMapping("tractAnnotation")
        public User traceAnnotation(
                @RequestParam("name") String name
        ) {
            log.info("从前端接收到的参数:[{}]", name);
            User user = trace(name);
            ActiveSpan.tag("new-tag", user.toString());
            ActiveSpan.info("输出信息");
            log.info("tractId:[{}]", TraceContext.traceId());
            return user;
        }
    
        @Trace(operationName = "添加自定义的方法")
        @Tags({
                @Tag(key = "从方法参数中获取值", value = "arg[0]"),
                @Tag(key = "从返回值中获取值", value = "returnedObj.name")
        })
        private User trace(String name) {
            log.info("如果此方法没有被SkyWalking收集,但是又需要被收集到,可以加上@Trace注解");
            User user = new User();
            user.setName("创建的名字");
            return user;
        }
    
    Trace注解的使用

    4、自定义显示服务实例

    默认服务实例的名字是 uuid@hostname,这个在某些时候不一定好区分,因为我们希望自定义一个 instanceName 名字

    1、默认的实现

    默认的服务实例

    2、自定义实现

    使用 -Dskywalking.agent.instance_name=自定义的服务名即可。

    自定义实例服务名

    九、项目源码

    docker-compose.yml文件 https://gitee.com/huan1993/configuration/blob/master/docker/compose/skywalking/skywalking.yml
    java代码 https://gitee.com/huan1993/skywalking

    十、参考链接

    SkyWalking官网 http://skywalking.apache.org/zh/
    SkyWalking的docker github地址 https://github.com/apache/skywalking-docker
    elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html
    skywalking中文文档 https://skyapm.github.io/document-cn-translation-of-skywalking/
    agent config https://github.com/apache/skywalking/blob/v8.0.1/docs/en/setup/service-agent/java-agent/README.md#table-of-agent-configuration-properties

    相关文章

      网友评论

        本文标题:skywalking实现分布式系统链路追踪

        本文链接:https://www.haomeiwen.com/subject/pbvzqktx.html