前言
基于微服务架构构建的应用,如果不能看到一个接口从前端发起到后端各个应用的调用链路,在排查问题,应用监控方面都会比较困难,所以实现微服务的调用链路追踪时非常有必要的。
本文基于SpringCloudSleuth + SpringCloudZipKin来实现微服务的调用链路追踪。
主要jar包版本
- Dubbo 2.6.10.1
- Springboot 2.3.12.RELEASE
- SpringCloudZipKin 2.2.8.RELEASE
- SpringCloudSleuth 2.2.8.RELEASE
搭建zipkin本地环境
下载并启动
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
访问
浏览器访问如下路径就可以看到zipkin的web界面了。
localhost:9411/zipkin
搭建微服务应用
基于SpringBoot + Dubbo构建一个简单的微服务体系。包括一个dubbo provider应用,dubbo consumer应用。
整体目录结构
父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>
<groupId>com.example</groupId>
<artifactId>springboot-dubbo-zipkin-sleuth-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>springboot-dubbo-zipkin-sleuth-example</name>
<description>springboot-dubbo-zipkin-sleuth-example</description>
<modules>
<module>dubbo-provider</module>
<module>dubbo-consumer</module>
<module>dubbo-api</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
<version>5.13.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建dubbo-api
定义测试接口
public interface DemoService {
String sayHello(String name);
}
创建dubbo provider
- 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>springboot-dubbo-zipkin-sleuth-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-provider</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- 启动类
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
- 接口实现
@Service
@Slf4j
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
return "Hello" + name;
}
}
- application.properties
server.port=8100
spring.application.name=dubbo-provider
spring.sleuth.sampler.rate=100
spring.zipkin.base-url=http://127.0.0.1:9411/
spring.zipkin.enabled=true
dubbo.application.name=provider
dubbo.application.id=provider
dubbo.application.version=1.0.0
dubbo.application.qos.port=2224
dubbo.protocol.server=netty
dubbo.protocol.name=dubbo
dubbo.protocol.port=20882
dubbo.protocol.threadpool=fixed
dubbo.protocol.threads=500
dubbo.protocol.queues=1000
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.provider.timeout=5000
dubbo.provider.retries=1
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
# 重要配置
dubbo.consumer.filter=tracing
dubbo.provider.filter=tracing
# 重要配置
logging.level.root=info
logging.pattern.console=[%p][%t][%d{yyyy-MM-dd HH:mm:ss.SSS}][%c][%L][%X{traceId}][%X{spanId}]%m%n
创建dubbo consumer
- 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>springboot-dubbo-zipkin-sleuth-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-consumer</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- application.properties
server.port=8101
spring.application.name=dubbo-consumer
spring.sleuth.sampler.rate=100
spring.zipkin.base-url=http://127.0.0.1:9411/
spring.zipkin.enabled=true
dubbo.application.name=consumer
dubbo.application.id=consumer
dubbo.application.version=1.0.0
dubbo.application.qos.port=2223
dubbo.protocol.server=netty
dubbo.protocol.name=dubbo
dubbo.protocol.port=20886
dubbo.protocol.threadpool=fixed
dubbo.protocol.threads=500
dubbo.protocol.queues=1000
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.provider.timeout=5000
dubbo.provider.retries=1
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
# 重要配置
dubbo.consumer.filter=tracing
dubbo.provider.filter=tracing
# 重要配置
logging.level.root=info
logging.pattern.console=[%p][%t][%d{yyyy-MM-dd HH:mm:ss.SSS}][%c][%L][%X{traceId}][%X{spanId}]%m%n
- 测试controller
@RestController
@RequestMapping
@Slf4j
public class HelloController {
@Reference(retries = 0)
DemoService demoService;
@GetMapping("/helloDubbo")
public String helloDubbo() {
return demoService.sayHello("haha");
}
}
验证
终端访问接口:
curl http://localhost:8101/helloDubbo
可以看到调用信息,点击show后可以看到详细的调用链路,这样一个简单链路追踪功能就搭建好了。
总结
zipkin默认将数据保存内存中,重启zipkin后数据就会丢失,在正式环境肯定是不合适的,官方提供了多种数据存储方式,包括mysql、es等,可根据具体需要参照官方文档实现。