微服务集成skywalking实现全链路日志追踪方案

目录

1、安装部署skywalking

1.1 环境准备

1.2 部署步骤

2、微服务整合skywalking实现链路监控

2.1 下载skywalking官方版本

2.2 将微服务引入skywalking监控

2.3 以上配置完成后启动服务即可实现链路监控

3、通过logback+ELFK实现全链路日志追踪

3.1 安装ELFK

3.2 添加依赖

3.3 logback文件配置

3.4 重启项目,调用测试接口

3.5 filebeat采集日志文件通过logstash输出到es

3.6 按上述配置启动filebeat,重新调用测试接口

4、tranceId在异步线程和feign调用过程中的传递

4.1 异步链路监控

4.2 feign调用的链路监控


1、安装部署skywalking

本节介绍通过docker-compose安装skywalking+es

1.1 环境准备

  • 安装docker和compose

1.2 部署步骤

  • 创建目录

mkdir -p /usr/local/skywalking/
cd /usr/local/skywalking/

  • 编写compose文件

vim docker-compose.yml

version: '3.8'
services:
  elasticsearch:
    image: elasticsearch:7.14.1
    container_name: elasticsearch
    restart: always
    ports:
      - 9200:9200
    healthcheck:
      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - TZ=Asia/Shanghai
    ulimits:
      memlock:
        soft: -1
        hard: -1
  oap:
    image: apache/skywalking-oap-server:8.1.0-es7
    container_name: oap
    depends_on:
      - elasticsearch
    links:
      - elasticsearch
    restart: always
    ports:
      - 11800:11800
      - 12800:12800
    healthcheck:
      test: ["CMD-SHELL", "/skywalking/bin/swctl"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    environment:
      TZ: Asia/Shanghai
      SW_STORAGE: elasticsearch7
      SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
  ui:
    image: apache/skywalking-ui:8.1.0
    container_name: ui
    depends_on:
      - oap
    links:
      - oap
    restart: always
    ports:
      - 8080:8080
    environment:
      TZ: Asia/Shanghai
      SW_OAP_ADDRESS: oap:12800
  • 启动

docker-compose up -d 

  • 访问首页(localhost:8080)

2、微服务整合skywalking实现链路监控

2.1 下载skywalking

https://archive.apache.org/dist/skywalking/8.1.0/apache-skywalking-apm-es7-8.1.0.tar.gz

2.2 微服务引入skywalking监控

  • 将下载的安装包解压到/usr/local/skywalking目录,找到skywalking-agent.jar

apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar

  • 将上述agent路径配置到微服务启动参数中,并配置环境变量如下:

-javaagent:/usr/local/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar -Dskywalking.agent.service_name=art-mall-1 -Dskywalking.collector.backend_service=localhost:11800 

参数解释:

/usr/local/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar本地agent的jar包位置
-Dskywalking.agent.service_name=art-mall-1注册到skywalking上的服务名称
-Dskywalking.collector.backend_service=localhost:11800skywalking接收agent发送采集数据的服务及端口

2.3 以上配置完成后启动服务即可实现链路监控

  • 仪表盘

  • 拓扑图

  • 追踪

3、通过logback+ELFK实现全链路日志追踪

3.1 安装ELFK

es在第一节中已安装,其他请自行百度安装!               

3.2 添加依赖

版本号与前面的skywalking对应 

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

<!-- 该引用用于代码获取tranceId -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.1.0</version>
</dependency>

3.3 logback文件配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!--用于区分不同应用程序的记录-->
    <contextName>art-logback</contextName>

    <!--日志文件所在目录,如果是tomcat,如下写法日志文件会在则为${TOMCAT_HOME}/bin/logs/目录下-->
    <!--    <property name="LOG_HOME_WINDOWS" value="logs"/>-->
    <property name="LOG_HOME_WINDOWS" value="D:/temp/logs"/>
    <property name="LOG_HOME_LINUX" value="./logs"/>

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式   [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n  -->
    <property name="CONSOLE_LOG_MDC_PATTERN" value="${CONSOLE_LOG_MDC_PATTERN:-%clr(%d{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}}"/>
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!--控制台-->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--    获取skywalking自动生成的tid    -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
                <pattern>${CONSOLE_LOG_MDC_PATTERN}</pattern>
            </layout>
        </encoder>
    </appender>

    <!--滚动文件-->
    <appender name="infoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- ThresholdFilter:临界值过滤器,过滤掉 TRACE 和 DEBUG 级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_LINUX}/info/info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--            <maxFileSize>100MB</maxFileSize>&lt;!&ndash;单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1&ndash;&gt;-->
            <maxHistory>30</maxHistory><!--保存最近30天的日志-->
            <totalSizeCap>20GB</totalSizeCap><!--所有的日志文件最大20G,超过就会删除旧的日志-->
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!--滚动文件-->
    <appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- ThresholdFilter:临界值过滤器,过滤掉 TRACE 和 DEBUG 级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>error</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_LINUX}/error/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--            <maxFileSize>100MB</maxFileSize>&lt;!&ndash;单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1&ndash;&gt;-->
            <maxHistory>30</maxHistory><!--保存最近30天的日志-->
            <totalSizeCap>20GB</totalSizeCap><!--所有的日志文件最大20G,超过就会删除旧的日志-->
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!--配置多环境日志输出  可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
    <!--本地或开发环境:打印控制台-->
    <springProfile name="local">
        <root level="debug">
            <appender-ref ref="stdout" />
            <!-- 为在本地测试日志输出到文件然后通过filebeat采集,此处同样输出到文件-->
            <appender-ref ref="infoFile" />
            <appender-ref ref="errorFile" />
        </root>
    </springProfile>
    <!--生产环境:输出到文件-->
    <springProfile name="prod">
        <root level="info">
            <appender-ref ref="infoFile" />
            <appender-ref ref="errorFile" />
        </root>
    </springProfile>

</configuration>

配置项解释:

  • org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout

       logback通过配置该layout可获取skywalking生成的tranceId

  • [%X{tid}]

        可在日志的对应位置打印出tranceId,如:

        [TID:5f6c5312b8e7445187565b1cb7368cd7.94.16340474835950001]

3.4 重启项目,调用测试接口

  •  测试接口
@PostMapping(value = "/test")
public ArtMallResult testTranceId(@RequestParam String id){
    log.info("测试日志打印tranceId");
    return ArtMallResultBuild.buildSuccess("success");
}
  • 日志打印如下:
2021-10-12 22:17:18.297 [TID:5ccddc5f4d364a38bcad8e9ebbd3e18e.93.16340482375740001]  INFO 3417 --- [nio-8085-exec-1] c.y.y.a.m.c.c.PCCommodityController      : 测试日志打印tranceId

3.5 filebeat采集日志文件通过logstash输出到es

中间通过logstash中转是因为其有更好的过滤功能,可视情况决定是否使用logstash。

  • filebeat.yml配置文件
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/logs/info/*.log
  multiline.pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:'
  multiline.negate: false
  multiline.match: after

output.logstash:
  hosts: ["10.20.178.216:8080"]
  • filebeat启动命令中将本地日志文件位置挂载到容器中
docker run --name=filebeat \
  --restart=always \
  -v /Users/isen/Desktop/develop/filebeat:/usr/share/filebeat \
  -v /xxx/xxx/xxx/logs:/var/log/logs \
  store/elastic/filebeat:7.15.0

3.6 按上述配置启动filebeat,重新调用测试接口

        可在kibana中通过tranceId快速检索整个链路上的所有日志,解决跨服务调用时全链路日志查询的不便。

4、tranceId在异步线程和feign调用过程中的传递

4.1 异步链路监控

        通过对Callable、Runnable、Supplier这三种接口的实现进行增强拦截,将trance的上下文信息传递到子线程中,实现了异步链路追踪。

原始类

提供的包装类

拦截方法

使用方式

Callable<V>

CallableWrapper<V>

call

CallableWrapper.of(xxxCallable)

Runable

RunableWrapper

run

RunnableWrapper.of(xxxRunable)

Supplier<V>

SupplierWrapper<V>

get

SupplierWrapper.of(xxxSupplier)

  • 使用方式:

        1、引入依赖,参考3.2第二个maven依赖

        2、定义线程池

@Configuration
public class ThreadPoolExecutorConfig {

    @Bean("testThreadPool")
    public ThreadPoolTaskExecutor testThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int core = Runtime.getRuntime().availableProcessors();
        executor.setCorePoolSize(core);
        executor.setMaxPoolSize(core * 2 + 1);
        executor.setKeepAliveSeconds(3);
        executor.setQueueCapacity(15000);
        executor.setThreadNamePrefix("testThreadPool");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

         3、修改测试接口,此处以RunnableWrapper和CallableWrapper为例

/**
 * 测试tranceId的效果
 * 未配置忽略追踪
 * @return
 */
@PostMapping(value = "/test1")
public ArtMallResult testTranceId(@RequestParam String id){
    ActiveSpan.tag("type", "异步任务多线程任务");
    testThreadPool.submit(RunnableWrapper.of(() -> {
        ActiveSpan.tag("type", "测试异步1");
        log.info("1-testThreadPool 测试一下tranceId的异步传递...");
    }));
    testThreadPool.submit(CallableWrapper.of(() -> {
        ActiveSpan.tag("type", "测试异步2");
        log.info("2-testThreadPool 测试一下tranceId的异步传递...");
        return null;
    }));
    return ArtMallResultBuild.buildSuccess("success");
}

        4、打印日志如下:

2021-10-13 10:31:53.605 [TID:2096e377f09744ac8004aaa0877bc707.91.16340923134680001]  INFO 4404 --- [nio-8085-exec-1] com.yun.ying.art.mall.filter.CorsFilter  : request path : /pc/commodity/test1
2021-10-13 10:31:54.348 [TID:2096e377f09744ac8004aaa0877bc707.91.16340923134680001]  INFO 4404 --- [testThreadPool1] c.y.y.a.m.c.c.PCCommodityController      : 1-testThreadPool 测试一下tranceId的异步传递...
2021-10-13 10:31:54.365 [TID:2096e377f09744ac8004aaa0877bc707.91.16340923134680001]  INFO 4404 --- [testThreadPool2] c.y.y.a.m.c.c.PCCommodityController      : 2-testThreadPool 测试一下tranceId的异步传递...

        5、链路追踪展示

4.2 feign调用的链路监控

参考第2节内容,为每个微服务都整合skywalking的链路监控即可

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值