前言
之前文章我们已经了解到搭建微服务架构的常用组件,使用它们搭建起一个基础的微服务架构系统来实现我们的业务需求了。但是,随着业务的发展,我们的系统规模也会变得越来越大,各微服务间的调用关系也变得越来越错综复杂。这时,一个Rerquest
访问系统,链路会经过后端不同的服务,这样每个请求都会有复杂的请求链,那链路跟踪日志就很有必要引入,它能帮助我们快速的发现错误根源以及监控分析每条请求链路上的性能瓶颈等好处。
Spring Cloud Sleuth
快速入门
在介绍各种概念与原理之前,我们先通过实现一个简单的示例,对存在服务调用的应用增加一些sleuth的配置实现基本的服务跟踪功能,以此来对Spring Cloud Sleuth有一个初步的了解,随后再逐步展开介绍实现过程中的各个细节部分。
准备工作
在引入Sleuth之前,我们先按照之前章节学习的内容来做一些准备工作,构建一些基础的设施和应用:
- 服务注册中心:eureka-server,这里不做赘述,直接使用之前构建的工程。或者直接使用我的公益eureka注册中心,下面的例子使用该注册中心。
- 微服务应用:trace-1,实现一个REST接口/trace-1,调用该接口后将触发对trace-2应用的调用。具体实现如下:
pom.xml
:如下
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 创建应用主类,并实现/trace-1接口,并使用RestTemplate调用trace-2应用的接口。具体如下:
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class TraceApplication {
private final Logger logger = Logger.getLogger(getClass());
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping(value = "/trace-1", method = RequestMethod.GET)
public String trace() {
logger.info("===call trace-1===");
return restTemplate().getForEntity("http://trace-2/trace-2", String.class).getBody();
}
public static void main(String[] args) {
SpringApplication.run(TraceApplication.class, args);
}
}
application.properties
中将eureka.client.serviceUrl.defaultZone
参数指向eureka-server的地址,具体如下:
spring.application.name=trace-1
server.port=9101
eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/
- 微服务应用:trace-2,实现一个REST接口/trace-2,供trace-1调用。具体实现如下:
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class TraceApplication {
private final Logger logger = Logger.getLogger(getClass());
@RequestMapping(value = "/trace-2", method = RequestMethod.GET)
public String trace() {
logger.info("===<call trace-2>===");
return "Trace";
}
public static void main(String[] args) {
SpringApplication.run(TraceApplication.class, args);
}
}
application.properties
中将eureka.client.serviceUrl.defaultZone
参数指向eureka-server的地址,另外还需要设置不同的应用名和端口号,具体如下:
spring.application.name=trace-2
server.port=9102
eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/
在实现了上面内容之后,我们可以将eureka-server
、trace-1
、trace-2
三个应用都启动起来,并通过postman或curl等工具来对trace-1的接口发送请求http://localhost:9101/trace-1
,我们可以得到返回值Trace,同时还能在它们的控制台中分别获得下面的输出:
-- trace-1
INFO 25272 --- [nio-9101-exec-2] ication$$EnhancerBySpringCGLIB$$36e12c68 : ===<call trace-1>===
-- trace-2
INFO 7136 --- [nio-9102-exec-1] ication$$EnhancerBySpringCGLIB$$52a02f0b : ===<call trace-2>===
实现跟踪
为上面的trace-1和trace-2来添加服务跟踪功能,需要新增POM.XML
的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
到这里,实际上我们已经为trace-1和trace-2实现服务跟踪做好了基础的准备,重启trace-1和trace-2后,再对trace-1的接口发送请求http://localhost:9101/trace-1
。此时,我们可以从它们的控制台输出中,窥探到sleuth的一些端倪。
2020-05-22 14:21:39.384 INFO [trace-1,f7c562a0753f5420,f7c562a0753f5420,false] 15348 --- [nio-9101-exec-8] ication$$EnhancerBySpringCGLIB$$ea77630b : ===<call trace-1>===
2020-05-22 14:21:39.393 INFO [trace-2,f7c562a0753f5420,08f548e411c8d7b8,false] 2488 --- [nio-9102-exec-3] ication$$EnhancerBySpringCGLIB$$57ea91cd : ===<call trace-2, TraceId=f7c562a0753f5420, SpanId=08f548e411c8d7b8>===
- 第一个值:trace-1,它记录了应用的名称,也就是application.properties中spring.application.name参数配置的属性。
- 第二个值:f410ab57afd5c145,Spring Cloud Sleuth生成的一个ID,称为Trace ID,它用来标识一条请求链路。一条请求链路中包含一个Trace ID,多个Span ID。
- 第三个值:a9f2118fa2019684,Spring Cloud Sleuth生成的另外一个ID,称为Span ID,它表示一个基本的工作单元,比如:发送一个HTTP请求。
- 第四个值:false,表示是否要将该信息输出到Zipkin等服务中来收集和展示。