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
文章目录
- SpringBoot SpringCloud Sleuth Zipkin Dubbo日志链路追踪全流程
- 1.步骤
- 1)先下载Zipkin jar包
- 2)运行Jar
- 3)启动Zipkin服务器
- 4)查看Zpikin界面
- 2.Pay 支付项目
- 1) 支付 pay项目
- 3.Buyer 买家项目
- 1) 买家 Buyer项目
- 2)配置Buyer 项目pom
- 3)配置Buyer 项目 application.properties
- 4)引入Log4j2配置文件
- 5)引入项目测试类Controller
- 5)启动项目、测试Http请求
- 4.Dubbo链路追踪
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 串联起来的,实现了链路追踪
大功告成!