SpringBoot Zipkin Dubbo Rpc 调用链路追踪完整流程 (一)

SpringBoot Zipkin Dubbo Rpc Http日志链路追踪全流程(一)

先拍砖,这个流程你跑不通,或者说Dubbo调用时候服务提供者、消费者 traceId不能串联起来、直接来拍我,有一个我接一个!!!!!!

说明:
本次主要针对 2.7.x Dubbo版本的调用实现链路追踪,众所周知,2.7.x Dubbo由org.apache开始维护,不再由 com.alibaba维护

我们实现微服务RPC通信,至少两个项目,先构建提供者 订单微服务, 再构建消费者 用户微服务,实现 用户微服务 调用 订单微服务 的链路追踪


1.准备工作
1)先下载Zipkin jar包

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

2)下载zookeeper的包,安装配置zk

我是windows系统,先在本地安装 zookeeper
因为使用的Dubbo rpc通信,所以你要有一个微服务消费者,和一个微服务提供者,而服务提供者就是注册在zk上的
我的版本是 apache-zookeeper-3.6.2
下载地址 链接:https://pan.baidu.com/s/1AT22bhIq8dN-zYf1hnqUww
提取码:rkud
下载后,进行安装,安装zk我就不讲了,可以自己搜一下
然后找到安装目录下的 bin/zkCli.cmd 启动客户端
看到 Welcome to ZooKeeper! 启动成功
在这里插入图片描述
测试下zk命令

#查看根节点下路径信息
ls /
#查看 /dubbo 路径下节点信息,能执行命令,就说明问题不大
#没有这两个RpcService是正常的,你还没启动服务,服务没注册上去
ls /dubbo

在这里插入图片描述

3)项目架构

本项目采用 SpringBoot 2.4.2 + Zipkin + Dubbo 2.7.x 实现


在这里说一下坑,我为什么不直接用sleuth 来配置,想看 sleuth实现Http调用的链路追踪 可以看下我的文章 SpringBoot SpringCloud Sleuth Zipkin实现 链路追踪
不能实现Dubbo的Rpc调用链追踪,因为sleuth要引入新的包,比较坑的是 一个包 brave-instrumentation-dubbo、brave-instrumentation-dubbo-rpc 这个包很坑,大家都知道 dubbo在 2.6.x之前 是由 com.alibaba 来维护的,groupId都是 com.alibaba的
从dubbo 2.7.x 版本后,由apache来维护了,所以 groupId 变成了 org.apache.dubbo, 2.6.x和 2.7.x 区别还是蛮大的
官方给的issud是:
brave-instrumentation-dubbo-rpc only support for 2.6.x.
The newest version of Dubbo is 2.7.x.The package has changed.The new package is start with org.apache.dubbo.
所以说 你用的Dubbo 如果是 2.6.x的, 用 sleuth没问题,引入 brave-instrumentation-dubbo-rpc
如果你是用Dubbo 2.7.x 要引入 brave-instrumentation-dubbo 版本来实现
实际上我引入了sleuth和brave-instrumentation-dubbo 依旧不会简单的实现打印TraceId,rpc provider和consumer串联(也有可能是哪里搞错了,后期跟踪源码定位下问题)


所以 今天我写了这个文章,来实现SpringBoot Zipkin Dubbo Rpc Http日志链路追踪全流程

2.本地部署Zipkin服务器

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

1)运行Jar

在这里插入图片描述

2)启动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) 说明启动成功
在这里插入图片描述

3)查看Zpikin界面

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

3.本地部署Zookeeper服务器并启动

测试zk命令正常,zk端口为2181,注册地址为 zookeeper://127.0.0.1:2181
在这里插入图片描述

4.配置项目B order

先说下项目结构 Dubbo通信同过接口访问 比如A->B A调用B的dubbo接口。
一般来说 都是B提供一个 client 的jar包, A项目引用 这个 jar包, 然后 通过调用Jar包中暴露的接口,此接口的实现一般在B服务中,这样才能实现 A项目通过Rpc 调用B项目的接口,等于A把B服务中接口的方法,当作本地方法来使用
所以项目结构 B项目有一个 client Jar,和 一个web应用
例如 订单服务B, order 和order-client 两个模块, order-client用户暴露接口

1) 构建Springboot项目 order,不需要依赖

在IDEA 中新建maven 项目 order ,order分为 order-client、order-webapp两个子Module项目, 父项目 不需要依赖dependencies不选择插件(因为父项目都是pom类型的)
在这里插入图片描述

2)解压项目,然后 IDEA打开项目 order

然后 删除src 下面的所有文件
在这里插入图片描述
删除src下面的所有文件后, 删除依赖 ,删除build的标签内容, 修改 父工程pom 的打包信息
packaging pom 查看目录结构
在这里插入图片描述
删除 Build 标签及下面的 信息 ,因为 order是 从Spring boot 项目删除src 出来的,build会找 springboot的信息,所以删除 build,否则 你编译会报错!!!!
删除 Build 标签及下面的 信息 !!!
删除 Build 标签及下面的 信息 !!!
删除 Build 标签及下面的 信息 !!!

Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.4.2:repackage (repackage) on project order-client: 
Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.4.2:repackage failed: Unable to find main class -> [Help 1]

删除完后, 项目order 的 pom 是这个样子(此时先忽略 module order-client及 order-webapp,因为还没建子 module)
在这里插入图片描述

5.构建项目 order-client 子工程

删除完 src后, 在order项目上右键,新建module ,选择maven项目 ,记住 mave项目, 新建order-client
选择maven项目
在这里插入图片描述
构建 order-client
定义order-client 路径信息,finish
在这里插入图片描述

查看 结果,新增 order-client的 pom 的打包信息 jar ,查看 order-client 的pom中有父依赖 parent, order的 pom 中有子module order-client

在这里插入图片描述

6.构建项目 order-webapp 子工程

再一次,在order项目上右键,新建module ,选择 maven项目, 记住 maven项目, 新建order-webapp,order的另一个子工程 order-webapp

选择maven项目
在这里插入图片描述
构建 order-webapp

定义order-webapp 路径信息,finish
在这里插入图片描述

查看结果, order-webapp 的pom中有父依赖 parent, order的 pom 中有子module order-webapp
在这里插入图片描述

有时候 如果你看到 web-app中的 src/java 不是蓝色的、src/resources 不是resources 带标记的
你可以自行设置下就OK了
java设置Sources Root 代码, resources设置ResourcesRoot 资源
在这里插入图片描述

7.配置项目 order、order-client、order-webapp

因为是父子多 module 项目,所以 我们采用 dependencyManager来管理 项目依赖包版本,防止 在子项目中各自定义自己项目的 jar包版本

所有子项目的 依赖包的版本都有 父 pom 制定,所有子pom都用的一个版本,便于版本管理

1)配置order的pom

主要定义 springboot版本 2.4.2,dubbo 版本 2.7.7,zk版本,brave版本,zipkin版本等等

order的pom.xml如下

<?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>
    <modules>
        <module>order-client</module>
        <module>order-webapp</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jzj</groupId>
    <artifactId>order</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order</name>
    <description>Demo project for Spring Boot</description>
    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
        <dubbo.version>2.7.7</dubbo.version>
        <brave-bom.version>5.13.3</brave-bom.version>
        <zipkin.version>2.16.3</zipkin.version>
        <curator.version>4.0.1</curator.version>
    </properties>


    <dependencyManagement>
        <dependencies>

            <!--  项目相关微服务依赖      -->
            <dependency>
                <groupId>com.jzj</groupId>
                <artifactId>order-client</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>


            <!--brave、zipkin依赖-->
            <dependency>
                <groupId>io.zipkin.brave</groupId>
                <artifactId>brave-bom</artifactId>
                <version>${brave-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.zipkin.reporter2</groupId>
                <artifactId>zipkin-reporter-bom</artifactId>
                <version>${zipkin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

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

            <!--Dubbo依赖 -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <artifactId>log4j</artifactId>
                        <groupId>log4j</groupId>
                    </exclusion>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
                <type>pom</type>
            </dependency>
            <!--zookeeper 客户端注册中心依赖-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>${curator.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>${curator.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

</project>

2)配置order-client 的pom

order-client的pom不变,依旧是原来的简单的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>order</artifactId>
        <groupId>com.jzj</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-client</artifactId>

    <packaging>jar</packaging>


</project>
3)配置order-webapp的pom

order-webapp的pom, 不需要指定版本,因为版本都在 父pom order的pom中通过 dependencyManagerment 管理了

<?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>order</artifactId>
        <groupId>com.jzj</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-webapp</artifactId>


    <dependencies>

        <!--  项目相关依赖      -->
        <dependency>
            <groupId>com.jzj</groupId>
            <artifactId>order-client</artifactId>
        </dependency>

        <!--   SpringBoot 相关依赖     -->
        <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>

        <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>
        </dependency>

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


        <!-- SpringBoot 2.7.x Dubbo 版本 配置Zipkin-->
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-instrumentation-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-context-slf4j</artifactId>
        </dependency>
        <!--        tracing -->
        <dependency>
            <groupId>io.zipkin.reporter2</groupId>
            <artifactId>zipkin-sender-okhttp3</artifactId>
        </dependency>
        <!--        tracing  & mvc-->
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-instrumentation-spring-webmvc</artifactId>
        </dependency>
        <!--        tracing  & http-->
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-instrumentation-httpclient</artifactId>
        </dependency>


    </dependencies>

<!--为什么加这个 ,不加这个后期产生一个错误,在编译时候报错 Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources) on project order-webapp-->
    <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>
4) order-client子module中新建接口

在order-client中 src/main/java 下面新建 com.jzj.order.client 包

在这个 com.jzj.order.client 包下 新建接口 IOrderRpcService

package com.jzj.order.client.rpc;

/**
 * 当前描述:
 *
 * @author: jiazijie
 * @since: 2021/2/10 下午10:56
 */
public interface IOrderRpcService {
    /**
     * 获取order的RPC接口
     *
     * @param orderId
     * @return
     */
    String getOrderInfo(String orderId);
}

order-client 制作为Jar包 使用,提供给其他微服务 调用, 所以 删除 order-client的 resources 及 test目录
在这里插入图片描述

8.配置项目 order-webapp
1) order-webapp下 src/main/java下新建包 com.jzj.order

在包下,新建启动类 OrderApplication,配置dubbo包扫描 com.jzj.order
OrderApplication.java

package com.jzj.order;

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

@SpringBootApplication
@DubboComponentScan("com.jzj.order")
public class OrderApplication {

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

}

2).com.jzj.order包下新建service.rpcimpl 包

service.rpcimpl 用于存放 Dubbo接口IOrderRpcService的实现,在 service.impl包下新建实现类
OrderRpcServiceImpl.java

package com.jzj.order.service.rpcimpl;

import com.jzj.order.client.IOrderRpcService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@DubboService(interfaceClass = IOrderRpcService.class)
public class OrderRpcServiceImpl implements IOrderRpcService {

    private static final Logger log = LogManager.getLogger(OrderRpcServiceImpl.class);

    @Override
    public String getOrderInfo(String orderId) {
        log.info("调用 order 的rpc接口 orderId:{}", orderId);
        return "订单编号--->" + orderId;
    }
}

3)resources下新建application.properties

配置application.properties内容
log4j2需要指明日志配置的xml文件 如 resources下log4j下log4j2-dev.xml文件
配置order 微服务启动端口 9988
配置dubbo协议相关
配置zipkin配置相关

#项目配置
server.port=9988
spring.application.name=order-webapp
#项目配置

#Dubbo 配置
dubbo.protocol.name=dubbo
dubbo.application.name=order-webApplication
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.consumer.check=false
dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing

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

#zipkin配置
zipkin.base.url=http://127.0.0.1:9411/api/v2/spans
zipkin.enable=true
#zipkin配置

4)引入order-webapp微服务 Log4j2配置文件

在resources下新建log4j文件夹,然后新建 log4j2-dev.xml文件 修改自己的项目名 $PROJECT_NAME 及 项目日志存储路径 $FILE_PATH

要想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="order-webapp" />
        <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.order目录下新建 controller包,包中新建测试类SiteController, 保证测试http端口
http://localhost:9828/temp/ping
http://localhost:9988/temp/log
http://localhost:9988/temp/http

package com.jzj.order.controller;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;

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


    @Autowired
    private RestTemplate restTemplate;

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


    @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";
    }

    @RequestMapping("http")
    public Object httpQuery() {

        String roomUrl = "http://localhost:9988/temp/ping";
        URI ping = URI.create(roomUrl);
        String pingResult = restTemplate.getForObject(ping, String.class);

        return pingResult;
    }

}


6)引入项目配置类

在com.jzj.order包下新建autoconfig包
在autoconfig包下新建rest包,新建类RestTemplateConfig 用于使用RestTemplate封装http请求

package com.jzj.order.autoconfig.rest;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate配置类
 */
@Configuration
public class RestTemplateConfig {
 
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        return new RestTemplate(factory);
    }
 
    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(5000);//单位为ms
        factory.setConnectTimeout(5000);//单位为ms
        return factory;
    }
}

在autoconfig包下新建trace包,新建类TracingConfig用于使用链路追踪配置
注意几个变量 都是zipkin 使用的在 resources/application.properties中定义的
zipkin.base.url=http://127.0.0.1:9411/api/v2/spans 定义zipkin的地址
zipkin.enable=true

TraceingConfig配置

package com.jzj.order.autoconfig.trace;

import brave.CurrentSpanCustomizer;
import brave.SpanCustomizer;
import brave.Tracing;
import brave.context.slf4j.MDCScopeDecorator;
import brave.http.HttpTracing;
import brave.propagation.B3Propagation;
import brave.propagation.ExtraFieldPropagation;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.rpc.RpcTracing;
import brave.sampler.Sampler;
import brave.servlet.TracingFilter;
import brave.spring.webmvc.SpanCustomizingAsyncHandlerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import zipkin2.Span;
import zipkin2.codec.Encoding;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;

import javax.servlet.Filter;

/**
 * @author jzjie
 */
@Configuration
@Import(SpanCustomizingAsyncHandlerInterceptor.class)
public class TracingConfig extends WebMvcConfigurerAdapter {


    @Bean
    @ConditionalOnProperty(
            value = {"zipkin.enable"},
            matchIfMissing = false)
    Sender sender(@Value("${zipkin.base.url}") String url) {
        return OkHttpSender.newBuilder()
                .encoding(Encoding.PROTO3)
                .endpoint(url)
                .build();
    }


    /**
     * Configuration for how to buffer spans into messages for Zipkin
     */
    @Bean
    @ConditionalOnBean(Sender.class)
    AsyncReporter<Span> spanReporter(Sender sender) {
        AsyncReporter.Builder builder = AsyncReporter.builder(sender);
        builder.queuedMaxSpans(50000);
        builder.queuedMaxBytes(104857600);
        return builder.build();
    }


    /**
     * Controls aspects of tracing such as the service name that shows up in the UI
     */
    @Bean
    Tracing tracing(@Value("${dubbo.application.name}") String applicationName, @Value("${zipkin.enable:false}") Boolean enable, @Autowired(required = false) AsyncReporter spanReporter) {
        Tracing.Builder builder = Tracing.newBuilder()
                .localServiceName(applicationName)
                .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
                .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
                        // puts trace IDs into logs
                        .addScopeDecorator(MDCScopeDecorator.create())
                        .build()
                );
        if (enable) {
            builder.spanReporter(spanReporter);
            builder.sampler(Sampler.ALWAYS_SAMPLE);
        } else {
            builder.sampler(Sampler.NEVER_SAMPLE);
        }
        return builder.build();
    }

    @Bean
    SpanCustomizer spanCustomizer(Tracing tracing) {
        return CurrentSpanCustomizer.create(tracing);
    }

    /**
     * Decides how to name and tag spans. By default they are named the same as the http method
     */
    @Bean
    HttpTracing httpTracing(Tracing tracing) {
        return HttpTracing.create(tracing);
    }


    @Bean
    RpcTracing rpcTracing(Tracing tracing) {
        return RpcTracing.create(tracing);
    }

    /**
     * Creates server spans for http requests
     */
    @Bean
    Filter tracingFilter(HttpTracing httpTracing) {
        return TracingFilter.create(httpTracing);

    }

    @Autowired
    SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;

    /**
     * Decorates server spans with application-defined web tags
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webMvcTracingCustomizer);
    }

}

9.编译项目 order 编译通过, install 到本地库

先在order 的maven 管理中 clean项目,然后 install项目,查看是否编译成功,编译通过OK
在这里插入图片描述
如果编译 出错了,看下错误
如下错误:
Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources) on project order-webapp
那么注意,是你的pom文件 不全,引入 order-webapp pom文件中最后的那一部分 build 就可以解决这个错误

    <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>

10. 启动项目、测试Http请求

启动项目 OrderApplication 启动,如果报错 无法加载 com.jzj.order.OrderApplication的错误
请编辑配置一下 OrderApplication,如下:
在这里插入图片描述

SpringBoot项目启动成功
在这里插入图片描述

访问端口 9588 controller端口
http://127.0.0.1:9988/temp/ping
http://127.0.0.1:9988/temp/log
http://127.0.0.1:9988/temp/http

在这里插入图片描述

1)查看Log日志及Zipkin界面

Console端Log日志
在这里插入图片描述

Zipkin界面 访问:http://localhost:9411/
可以看到 有很多请求链路,都是刚才访问的 http请求
在这里插入图片描述
点击其中一个,展开看下
在这里插入图片描述

可以看到 日志中打印的traceId是 可以在 zipkin中追踪到的
在这里插入图片描述

到此为止,我们配置好了B 订单Order 微服务,并且它的 Http 是可以追踪的
要想实现Dubbo Rpc调用,从 用户User微服务, 调用 B Order微服务 ,我们还要配置好A user 微服务




下一篇 我们介绍 用户User RPC 微服务构建过程及 用户-》订单的调用链追踪过程
SpringBoot Zipkin Dubbo Rpc 调用链路追踪完整流程 (二)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Spring Boot 中整合 Zipkin 链路追踪需要进行以下步骤: 1. 在 pom.xml 中添加依赖: ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> ``` 2. 在 application.properties 中添加如下配置: ``` spring.zipkin.base-url=http://localhost:9411 ``` 3. 在启动类上添加 `@EnableZipkinServer` 注解开启 Zipkin 服务端功能。 示例代码如下: ``` @SpringBootApplication @EnableZipkinServer public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } } ``` 4. 在需要进行链路追踪的服务中添加依赖和配置: ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> ``` 在 application.properties 中添加如下配置: ``` spring.zipkin.base-url=http://localhost:9411 ``` 5. 在启动类上添加 `@EnableZipkinStreamServer` 注解开启 Zipkin 客户端功能。 示例代码如下: ``` @SpringBootApplication @EnableZipkinStreamServer public class ZipkinClientApplication { public static void main(String[] args) { SpringApplication.run(ZipkinClientApplication.class, args); } } ``` 以上就是在 Spring Boot 中整合 Zipkin 链路追踪的简单示例。希望这能帮到您。 ### 回答2: Zipkin是一个用于分布式系统的链路追踪工具,方便开发人员在微服务架构中进行系统性能监控和故障排查。下面是一个基于Spring Boot的Zipkin链路追踪的配置整合示例。 首先,我们需要在pom.xml文件中添加相关依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <!-- 其他相关依赖 --> </dependencies> ``` 接下来,在Spring Boot应用的启动类上添加@EnableZipkinServer注解,启用Zipkin Server功能: ```java @SpringBootApplication @EnableZipkinServer public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } } ``` 然后,我们需要在应用的配置文件application.properties中添加相关配置: ```properties spring.application.name=zipkin-server server.port=9411 spring.zipkin.enabled=true spring.sleuth.sampler.probability=1.0 spring.zipkin.base-url=http://localhost:9411 ``` 其中,spring.zipkin.enabled为true表示启用Zipkin功能,spring.sleuth.sampler.probability=1.0表示采样率为100%,spring.zipkin.base-url为Zipkin Server的地址。 最后,我们需要在每个需要进行链路追踪的Spring Boot应用上添加相关配置: ```properties spring.zipkin.baseUrl=http://localhost:9411 spring.zipkin.discovery-client-enabled=true spring.zipkin.communications.enabled=true spring.zipkin.sender.type=web ``` 其中,spring.zipkin.baseUrl为Zipkin Server的地址,spring.zipkin.discovery-client-enabled为true表示启动服务发现功能,spring.zipkin.communications.enabled为true表示启动基于HTTP的通信功能,spring.zipkin.sender.type为web表示使用web方式发送链路数据。 通过以上配置和整合,我们就可以在Spring Boot应用中实现Zipkin链路追踪监控和故障排查功能了。 ### 回答3: Zipkin是一个开源的分布式追踪系统,可以用于追踪微服务架构中的请求链路。在Spring Boot中整合Zipkin,可以通过配置和依赖注入来实现链路追踪功能。 首先,需要在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> ``` 接下来,在application.properties文件中添加以下配置: ```properties spring.zipkin.base-url=http://localhost:9411 # Zipkin服务器的地址 ``` 然后,创建一个Spring Boot应用程序,并在启动类上添加`@EnableZipkinServer`注解,以启用Zipkin服务器: ```java @SpringBootApplication @EnableZipkinServer public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } } ``` 在需要追踪的微服务应用程序中,需要添加以下配置: ```properties spring.zipkin.baseUrl=http://localhost:9411 # Zipkin服务器的地址 spring.sleuth.sampler.probability=1.0 # 采样比例,此处为100%采样 ``` 然后,在需要追踪的请求执行之前,添加以下注解: ```java @Autowired private Tracer tracer; ... Span span = tracer.getCurrentSpan(); span.tag("key", "value"); // 可以添加自定义的标签信息 ... span.finish(); ``` 这样就完成了Zipkin链路追踪功能的配置和整合。通过访问Zipkin服务器提供的界面,可以查看各个微服务之间的请求链路调用耗时。 总结:通过添加依赖和配置,以及使用Tracer来记录和追踪请求的执行情况,可以实现在Spring Boot应用程序中使用Zipkin进行链路追踪

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值