SpringBoot Sleuth Zipkin Dubbo日志链路追踪全流程(2)

2023-11-10

SpringBoot SpringCloud Sleuth Zipkin Dubbo日志链路追踪全流程

看这篇文章之前,你最好看一下 之前的文章 SpringBoot SpringCloud Sleuth Zipkin Http Log4j 链路追踪流程, 本文是 针对上个链接,http链路追踪的升级版,可以追踪Dubbo 微服务之间的调用
该项目组成 买家Buyer 微服务及Pay微服务 两个微服务构成, Buyer是SpringBoot项目,Pay微服务是 多Module父子项目,通过 pay-client 提供接口,供微服务 Buyer及Pay之间调用

另外,这篇文章和我之前写的
SpringBoot Zipkin Dubbo Rpc 调用链路追踪完整流程 (一)
SpringBoot Zipkin Dubbo Rpc 调用链路追踪完整流程 (二)

区别在于

本篇文章使用 SpringCloud Sleuth 来配置Dubbo rpc调用的链路追踪,上面的链接是纯SpringBoot 项目,不涉及SpringCloud 体系中的 sleuth jar 包及相关依赖的

项目依赖 SpringBoot 2.4.1 、SpringCloud 2020.0.1 、Dubbo版本 2.7.7、Zookeeper 3.4.11 、brave 5.13.2

1.步骤
1)先下载Zipkin jar包

这样你可以在本地先启动Zipkin服务 我的版本是zipkin-server-2.12.9-exec.jar 下载地址 链接:https://pan.baidu.com/s/1BV61J0c4EwWzC8OnBwQY8Q
提取码:898k 可以下载zipkin jar包

2)运行Jar

下载jar包后,直接到jar包目录,运行 java -jar java -jar zipkin-server-2.12.9-exec.jar
当你看到 Started ZipkinServer in 2.652 seconds (JVM running for 3.204) 表明运行成功
在这里插入图片描述

3)启动Zipkin服务器

注意 http://127.0.0.1:9411 是Zipkin服务器界面的入口
看到 Serving HTTP at /0:0:0:0:0:0:0:0:9411 - http://127.0.0.1:9411/
Started ZipkinServer in 2.602 seconds (JVM running for 3.149) 说明启动成功
在这里插入图片描述

4)查看Zpikin界面

浏览器输入 http://127.0.0.1:9411 你可以看到一下界面
在这里插入图片描述

2.Pay 支付项目
1) 支付 pay项目

项目结构如下:子module pay-client及 子module pay-webapp ,添加相关依赖
在这里插入图片描述

Pay 包下的 父Pom.xml
!!! 注意父pom 的package类型 为 pom,且由 来管理jar包版本,子module中不再定义版本信息

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.jzj</groupId>
    <artifactId>pay</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>pay-client</module>
        <module>pay-webapp</module>
    </modules>
    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <dubbo.version>2.7.7</dubbo.version>
        <zookeeper.version>3.4.11</zookeeper.version>
        <brave.version>5.13.2</brave.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--log4j 异步日志-->
            <dependency>
                <groupId>com.lmax</groupId>
                <artifactId>disruptor</artifactId>
                <version>3.3.6</version>
            </dependency>

            <!--dubbo-springBoot依赖-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>

            <!--zookeeper依赖-->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>${zookeeper.version}</version>
            </dependency>
            <!--zookeeper客户端注册中心依赖-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.0.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.0.1</version>
            </dependency>

            <!--  brave-dubbo 配置-->
            <dependency>
                <groupId>io.zipkin.brave</groupId>
                <artifactId>brave-instrumentation-dubbo</artifactId>
                <version>${brave.version}</version>
            </dependency>


            <!--    Zipkin要使用SpringCloud Sleuth    -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

子module pay-client pom及代码
pay-client pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <artifactId>pay</artifactId>
       <groupId>org.jzj</groupId>
       <version>1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>

   <artifactId>pay-client</artifactId>
   <packaging>jar</packaging>

</project>

pay-client 新建 com.jzj.pay.rpc 包,存放 rpc接口

package com.jzj.pay.rpc;

public interface IPayRpcService {
   /**
    * 消费者 付款
    *
    * @param user  消费者名字
    * @param price 付款
    * @return
    */
   String payMoney(String user, Integer price);

}

子module pay-webapp的 pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <artifactId>pay</artifactId>
       <groupId>org.jzj</groupId>
       <version>1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>

   <artifactId>pay-webapp</artifactId>

   <dependencies>
       <!--引入 client包-->
       <dependency>
           <groupId>org.jzj</groupId>
           <artifactId>pay-client</artifactId>
           <version>1.0-SNAPSHOT</version>
       </dependency>
       <!--   链路追踪 包-->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-sleuth</artifactId>
       </dependency>
       <!--  Zipkin 配置    -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-sleuth-zipkin</artifactId>
       </dependency>

       <!--  SpringBoot相关依赖      -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
           <exclusions><!-- 去掉springboot log默认配置 -->
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-logging</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
           <exclusions><!-- 去掉springboot log默认配置 -->
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-logging</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <!-- 引入log4j2依赖 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-log4j2</artifactId>
       </dependency>
       <!--log4j 异步日志-->
       <dependency>
           <groupId>com.lmax</groupId>
           <artifactId>disruptor</artifactId>
           <version>3.3.6</version>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>

       <!--dubbo-springBoot依赖-->
       <dependency>
           <groupId>org.apache.dubbo</groupId>
           <artifactId>dubbo-spring-boot-starter</artifactId>
           <version>${dubbo.version}</version>
       </dependency>

       <!--zookeeper依赖-->
       <dependency>
           <groupId>org.apache.zookeeper</groupId>
           <artifactId>zookeeper</artifactId>
           <version>${zookeeper.version}</version>
       </dependency>
       <!--zookeeper客户端注册中心依赖-->
       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-recipes</artifactId>
           <version>4.0.1</version>
       </dependency>
       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-framework</artifactId>
           <version>4.0.1</version>
       </dependency>

       <!-- SpringBoot 2.7.x Dubbo 版本 配置Zipkin-->
       <dependency>
           <groupId>io.zipkin.brave</groupId>
           <artifactId>brave-instrumentation-dubbo</artifactId>
           <version>${brave.version}</version>
       </dependency>

   </dependencies>
   
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>

           <!--在这里修改版本-->
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-resources-plugin</artifactId>
               <version>2.4.3</version>
           </plugin>
       </plugins>
   </build>

</project>

子module pay-webapp 的启动类 PayApplication

package com.jzj.pay;


import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@DubboComponentScan("com.jzj.pay.service")
public class PayApplication {

    public static void main(String[] args) {
        SpringApplication.run(PayApplication.class, args);
    }

}

子module pay-webapp 的 controller,新建 com.jzj.pay.controller包下的测试类

package com.jzj.pay.controller;

import com.jzj.pay.rpc.IPayRpcService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@ResponseBody
@RestController
@RequestMapping("temp")
public class SiteController {
    private static Logger log = LoggerFactory.getLogger(SiteController.class);

    @DubboReference
    private IPayRpcService payRpcService;


    @RequestMapping("ping")
    public Object ping() {
        log.info("进入ping");
        return "pong pay";
    }


    @RequestMapping("pay")
    public Object pay() {

        String result = payRpcService.payMoney("jzj", 10000);
        log.info("result:{}", result);
        return result;
    }


    @RequestMapping("log")
    public Object log() {
        log.info("this is info log");
        log.error("this is error log");
        log.debug("this is debug log");
        log.warn("this is warn log");
        log.trace("this is trace log");
        return "123";
    }
}

子module pay-webapp 的 rpc接口实现,新建包com.jzj.pay.service.rpc.impl

package com.jzj.pay.service.rpc.impl;

import com.jzj.pay.rpc.IPayRpcService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@DubboService(interfaceClass = IPayRpcService.class)
public class PayRpcServiceImpl implements IPayRpcService {

    private static Logger log = LoggerFactory.getLogger(PayRpcServiceImpl.class);

    @Override
    public String payMoney(String user, Integer price) {
        log.info("调用 支付微服务Pay 用户:{}, 支付:{} 元", user, price);
        return "User:" + user + " Pay:" + price;
    }
}

子module pay-webapp 的 resources下面的 application.properties配置
!!! 一定要配置 dubbo.provider.filter、dubbo.consumer.filter
!!! 一定要配置 dubbo.provider.filter、dubbo.consumer.filter
!!! 一定要配置 dubbo.provider.filter、dubbo.consumer.filter

#项目配置
server.port=9911
spring.application.name=pay-mini-service
#项目配置 end
   
#Dubbo 配置
dubbo.consumer.check=false
dubbo.protocol.name=dubbo
dubbo.application.name=pay
dubbo.registry.address=zookeeper://127.0.0.1:2181
#!!!很重要 不配置这个,产生的rpc链路不是完整的
dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing
#Dubbo 配置 end

#log日志配置
logging.config=classpath:log4j/log4j2-dev.xml
#log日志配置 end
        
#zipkin配置
spring.zipkin.base-url=http://127.0.0.1:9411/
spring.zipkin.enabled=true
spring.sleuth.sampler.probability=1
#zipkin配置 end

子module pay-webapp 的resources下新建 log4j/log4j2-dev.xml 日志配置, 修改自己的 PROJECT_NAME
!!! 一定要加入[%X{traceId},%X{spanId}]
!!! 一定要加入[%X{traceId},%X{spanId}]

!!! 一定要加入[%X{traceId},%X{spanId}]

<?xml version="1.0" encoding="UTF-8"?>
<!--
Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
当设置成trace时,可以看到log4j2内部各种详细输出
-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration monitorInterval="5">
    <!--日志级别以及优先级排序:
    OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL
    -->

    <!--变量配置-->
    <Properties>
        <!--
            格式化输出:
            %d表示日期,
            %thread表示线程名,
            %-5level:级别从左显示5个字符宽度
            %msg:日志消息,%n是换行符
        -->
        <!--
        %logger{36} 表示 Logger 名字最长36个字符
        -->
        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%X{traceId},%X{spanId}] %highlight{%-5level}[%thread] %style{%logger{36}}{cyan} : %msg%n" />
<!--        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%logger{50}:%L] [%X{X-B3-TraceId},%X{X-B3-SpanId}] - %msg%n" />-->

        <!-- 定义日志存储的路径,不要配置相对路径 -->
        <property name="PROJECT_NAME" value="pay" />
        <property name="FILE_PATH" value="E:\myworkspace\log\${PROJECT_NAME}" />
    </Properties>

    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/>

            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>

        </console>

        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="FileLog" fileName="${FILE_PATH}/test.log" append="false">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <!--
        这个会打印出所有的info及以下级别的信息,每次大小超过size,
        则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,
        作为存档
        -->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>

        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="FileLog"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>

</configuration>

编译、安装、启动项目,要让 pay-client安装到本地库,这样 其他项目buyer 再引用client包时候,才能加载到自己项目中

访问下 controller接口,看是否通及zipkin是否可用
1.项目console打印 traceId正常
2.zipkin链路追踪正常
3.controller 接口请求正常
在这里插入图片描述

3.Buyer 买家项目
1) 买家 Buyer项目

在这里插入图片描述

2)配置Buyer 项目pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jzj</groupId>
    <artifactId>buyer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>buyer</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <dubbo.version>2.7.7</dubbo.version>
        <zookeeper.version>3.4.11</zookeeper.version>
        <brave.version>5.13.2</brave.version>
    </properties>
    <dependencies>
        <!--引入 client包-->
        <dependency>
            <groupId>org.jzj</groupId>
            <artifactId>pay-client</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--   链路追踪 包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <!--  Zipkin 配置    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>

        <!--  SpringBoot相关依赖      -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions><!-- 去掉springboot log默认配置 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions><!-- 去掉springboot log默认配置 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 引入log4j2依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <!--log4j 异步日志-->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--dubbo-springBoot依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>

        <!--zookeeper依赖-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>
        <!--zookeeper客户端注册中心依赖-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.1</version>
        </dependency>

        <!-- SpringBoot 2.7.x Dubbo 版本 配置Zipkin-->
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-instrumentation-dubbo</artifactId>
            <version>${brave.version}</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!--在这里修改版本-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4.3</version>
            </plugin>
        </plugins>
    </build>
</project>

3)配置Buyer 项目 application.properties

配置application.properties相比logback,log4j2需要指明日志配置的xml文件 如 resources下log4j下log4j2-dev.xml文件

#项目配置
server.port=9912
spring.application.name=Buy-service
#项目配置 end

#Dubbo 配置
dubbo.consumer.check=false
dubbo.protocol.name=dubbo
dubbo.application.name=Buyer
dubbo.registry.address=zookeeper://127.0.0.1:2181
#!!!很重要 不配置这个,产生的rpc链路不是完整的
dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing
#Dubbo 配置 end

#log日志配置
logging.config=classpath:log4j/log4j2-dev.xml
#log日志配置 end

#zipkin配置
spring.zipkin.base-url=http://127.0.0.1:9411/
spring.zipkin.enabled=true
spring.sleuth.sampler.probability=1
#zipkin配置 end

4)引入Log4j2配置文件

在resources下新建log4j文件夹,然后新建 log4j2-dev.xml文件 修改自己的项目名
$PROJECT_NAME
要想log4j2打印TraceId、SpanId,不要听别人说要配置 [%X{X-B3-TraceId},%X{X-B3-SpanId}] 没卵用,重要事情说三遍
这个版本的只有按照这个配置才是可以生效的[%X{traceId},%X{spanId}]
这个版本的只有按照这个配置才是可以生效的[%X{traceId},%X{spanId}]
这个版本的只有按照这个配置才是可以生效的[%X{traceId},%X{spanId}]

Log4j2-dev.xml 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
当设置成trace时,可以看到log4j2内部各种详细输出
-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration monitorInterval="5">
    <!--日志级别以及优先级排序:
    OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL
    -->

    <!--变量配置-->
    <Properties>
        <!--
            格式化输出:
            %d表示日期,
            %thread表示线程名,
            %-5level:级别从左显示5个字符宽度
            %msg:日志消息,%n是换行符
        -->
        <!--
        %logger{36} 表示 Logger 名字最长36个字符
        -->
        <property name="LOG_PATTERN" value="[%d{yyy-MM-dd HH:mm:ss:SSS}]  [%X{traceId},%X{spanId}] %highlight{%-5level}[%thread] %style{%logger{36}}{cyan} : %msg%n" />

        <!-- 定义日志存储的路径,不要配置相对路径 -->
        <property name="PROJECT_NAME" value="buyer" />
        <property name="FILE_PATH" value="E:\myworkspace\log\${PROJECT_NAME}" />
    </Properties>

    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/>

            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>

        </console>

        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="FileLog" fileName="${FILE_PATH}/test.log" append="false">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <!--
        这个会打印出所有的info及以下级别的信息,每次大小超过size,
        则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,
        作为存档
        -->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${PROJECT_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>

        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="FileLog"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>

</configuration>

5)引入项目测试类Controller

在com.jzj.buyer目录下新建 controller包,包中新建测试类SiteController

package com.jzj.buyer.controller;

import com.jzj.pay.rpc.IPayRpcService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@ResponseBody
@RestController
@RequestMapping("temp")
public class SiteController {
    private static Logger log = LoggerFactory.getLogger(SiteController.class);

    @DubboReference
    private IPayRpcService payRpcService;


    @RequestMapping("ping")
    public Object ping() {
        log.info("进入ping");
        return "pong Buyer";
    }


    @RequestMapping("buyer-pay")
    public Object pay() {

        String result = payRpcService.payMoney("JZJ", 9999);
        log.info("result:{}", result);
        return result;
    }


    @RequestMapping("log")
    public Object log() {
        log.info("this is info log");
        log.error("this is error log");
        log.debug("this is debug log");
        log.warn("this is warn log");
        log.trace("this is trace log");
        return "123";
    }
}

5)启动项目、测试Http请求

启动项目,服务端口为9912,浏览器访问 http://127.0.0.1:9527/temp/ping
可以看到正常请求,zipkin及console 正常追踪
在这里插入图片描述

4.Dubbo链路追踪

访问 http://127.0.0.1:9912/temp/buy-pay ,从 Buyer 消费者项目 调用支付 Pay项目,属于微服务调用,看下结果
controller界面
在这里插入图片描述

查看Zipkin链路
在这里插入图片描述
可以看到 从 Buyer发起的 调用 链路 ,掉 用微服务 IPayRpcService 的方法 payMoney ,是通过 同一个TraceID 1dd8e8942e453ac9 串联起来的,实现了链路追踪

大功告成!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot Sleuth Zipkin Dubbo日志链路追踪全流程(2) 的相关文章

随机推荐

  • ElasticSearch第十八讲 ES-Master节点职责和ES是如何做到数据实时性的

    Elasticsearch Master 节点的职责 由主节点负责ping 所有其他节点 判断是否有节点已经挂掉 创建或删除索引 决定分片在节点之间的分配 稳定的主节点对集群的健康是非常重要的 虽然主节点也可以协调节点 路由搜索和从客户端新
  • 6.84 C++ 遍历数组的几种方式

    1 计算出数组长度进行遍历 数组类型确定 数组中每个元素本身的字节大小就已经确定 利用 sizeof 函数可以计算出数组长度 而后利用 for 循序进行数组的遍历 2 使用类似 foreach 的方式进行遍历 C 中也可使用类似 forea
  • AVI文件与WAV文件格式

    AVI 与WAV文件都属于RIFF文件 因此都遵循RIFF文件的格式要求 先看看RIFF文件的格式 第一 RIFF 大小 AVI WAV 数据 第二 RIFF 文件中实际的数据通常采用列表 list 和块 Chunk 的形式表示 列表结构为
  • 智能门锁电路图_蓝牙门锁原理图一览 蓝牙智能门锁工作原理介绍

    蓝牙智能门锁工作原理是什么 蓝牙门锁原理图步骤详解 蓝牙智能门锁主要是通过手机开锁的方式来解锁 相比传统门锁 蓝牙门锁更加便捷 此外 还可以通过手机APP来实现门锁实时管理 访客管理 是符合智能家居时代对门锁要求的电子产品 那么蓝牙智能门锁
  • tesseract api C++使用例子

    转自 https code google com p tesseract ocr wiki APIExample APIExample API examples Updated Aug 12 2014 by theraysm gmail c
  • unsigned int 和 signed int 的区别

    unsigned int 和 signed int 的区别 对于 int 类型 默认是带有正负号的 也就是说 int 等同于 signed int signed int 等同于int 都能表示正负数 1 signed int 可以表示正整数
  • SQL优化之LIMIT语法, limit n,m 和 limit n有什么区别?

    在某些面试题中会遇到这样的问答或笔试题 limit 0 1 和 limit 1有什么区别 要准确回答这个问题就等深入明白limit一个参数和两个参数的本质区别 limit n m 中的第一次参数n表示的游标的偏移量 初始值为0 第二个参数m
  • Codeforces Round #367 (Div. 2)【贪心、差分、DP、字典树、二维链表】

    Codeforces Round 367 Div 2 A Beru taxi 就是问 我们知道一个点 从其他点到它的最少花费的时间是多少 include
  • 三次握手,四次挥手白话文

    三次握手和四次挥手是TCP协议中用于建立和断开连接的过程 三次握手 Three way Handshake 客户端向服务器发送一个SYN 同步 包 其中包含一个随机的初始序列号 表示客户端请求建立连接 服务器收到客户端的SYN包后 向客户端
  • 2022互联网精英副业指南,看到程序员的我笑了~

    不得不说 互联网人收入高 如果你以为互联网人收入高是因为工资高 年终奖丰厚 那你就错了 其实 还有一个原因是他们搞起了副业 副业千万条 闲鱼第一条 万万没想到的是 互联网人在闲鱼上赚钱也与众不同 甚至都一个比一个拼 https mmbiz
  • 【Java 集合 & 数据结构】优先队列 PriorityQueue

    优先队列 PriorityQueue 一 概述 二 结构 三 解析 1 核心属性 2 核心方法 offer 方法 入队列 poll 方法 出队列 peek 方法 队头元素 最小元 四 特点 优点 缺点 一 概述 优先队列 PriorityQ
  • Android String字符串截取方法总结

    Android String字符串截取方法总结 指定字符 截取字符串 返回字符串数组 String str abcd efg 123456 hijk 345 String strs str split 指定索引号 截取字符串 将字符串从索引
  • 服务器上创建Python虚拟环境

    应用场景 不同的项目 或者同一项目的不同版本 需要安装不同的Python解释器和依赖库 对于有python版本依赖的程序来说 为了安全可靠的管理环境 需要创建不同版本的 独立 隔离 的虚拟环境 virtualenv 是一个创建隔绝的Pyth
  • Java设计与实现“秒杀”活动之抢粽子【完整版】

    五月榴花妖艳烘 绿杨带雨垂垂重 五月新丝缠角粽 金盘送 生绡画扇盘双凤 正是浴兰时节动 正值端午佳节 实习公司也是例行放假三天以及给每一位员工发放了节日小礼品 过完端午又将迎来618活动专场 秒杀抢单活动也是此起彼伏 从而产生刺激性消费 由
  • 使用HiBurn烧录鸿蒙.bin文件到Hi3861开发板

    使用HiBurn烧录鸿蒙 bin文件到Hi3861开发板 鸿蒙官方文档的 Hi3861开发板第一个示例程序 中描述了 如何使用DevEco Device Tool工具烧录二进制文件到Hi3861开发板 本文将介绍如何使用HiBurn工具烧录
  • 网站服务器放本地还是云上,服务器放本地还是云上安全

    服务器放本地还是云上安全 内容精选 换一换 在弹性云服务器上安装完成后输入公网IP 无法连接目的虚拟机 端口无法访问工具 源端网络未连通目的端 目的端安全组未开放8084端口 目的端网络ACL禁用了8084端口 登录源端服务器后 在源端服务
  • Leetcode 计算质数 -- 埃氏筛、线性筛解析

    0 题目描述 leetcode原题链接 204 计数质数 1 埃氏筛 很直观的思路是我们枚举每个数判断其是不是质数 枚举没有考虑到数与数的关联性 因此难以再继续优化时间复杂度 介绍一个常见的算法 该算法由希腊数学家厄拉多塞 Eratosth
  • C语言/实现MD5加密

    本文详细视频讲解 已经发布到B站 https www bilibili com video BV1uy4y1p7on 更多仔细 请关注公众号 一口Linux 一 摘要算法 摘要算法又称哈希算法 它表示输入任意长度的数据 输出固定长度的数据
  • C语言头文件路径相关问题总结说明

    聊聊系统路径位置 绝对路径与相对路径 正斜杠 与 反斜杠 使用说明 by 矜辰所致 目录 前言 一 C语言中的头文件引用 二 KEIL 中的头文件路径 2 1 IncudePaths 指定的路径 绝对路径和相对路径 正斜杠 与 反斜杠 与双
  • SpringBoot Sleuth Zipkin Dubbo日志链路追踪全流程(2)

    SpringBoot SpringCloud Sleuth Zipkin Dubbo日志链路追踪全流程 看这篇文章之前 你最好看一下 之前的文章 SpringBoot SpringCloud Sleuth Zipkin Http Log4j