1. 应用背景
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。如果在这个过程中出现了异常,就很难去定位问题。所以,必须要实现一个分布式链路跟踪
的功能,直观的展示出完整的调用过程。
如果想要诊断复杂操作,通常的解决方案是在请求中传递唯一的ID到每个方法来识别日志。Spring Cloud Sleuth
提供了一套完整的服务跟踪的解决方案 , 可以与日志框架Logback、SLF4J轻松地集成,通过添加独特的标识符来使用日志跟踪和诊断问题。
2. 整合Spring Cloud Sleuth
在网关微服务, 电影微服务和用户微服务
中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
添加日志输出代码:
private Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info("Doing some work");
日志的格式为:[application name, traceId, spanId, export]
- application name — 应用的名称,也就是application.properties中的spring.application.name参数配置的属性。
- traceId — 为一个请求分配的ID号,用来标识一条请求链路。
- spanId — 表示一个基本的工作单元,一个请求可以包含多个步骤,每个步骤都拥有自己的spanId。一个请求包含一个
TraceId,多个SpanId .- export — 布尔类型。表示是否要将该信息输出到类似Zipkin这样的聚合器进行收集和展示。
- TraceId和SpanId在两条日志中是相同的,即使消息来源于两个不同的类。这就可以在不同的日志通过寻找traceid来识别一个请> 求。
请求微服务,这里我通过网关访问电影微服务http://localhost:9004/microservice-movie/movie/order5
,然后查询日志. 可以看到有一个日志追踪号ff728007ec7fe75b
贯穿了整个请求周期.
网关微服务
日志追踪
电影微服务
日志追踪
用户微服务
日志追踪
3. Zipkin
3.1 Zipkin简介
单独使用Spring Cloud Sleuth
依靠控制台追踪日志的方法非常不方便!这时可以使用Zipkin来收集所有日志信息,更加直观.
Zipkin分布式跟踪
系统, 它可以帮助收集时间数据,解决在微服务架构下的延迟问题;它管理这些数据的收集和查找;Zipkin的设计是基于谷歌的Google Dapper论文。
每个应用程序向Zipkin
报告定时数据,Zipkin UI
呈现了一个依赖图
表来展示多少跟踪请求经过了每个应用程序;如果想解决延迟问题,可以过滤或者排序所有的跟踪请求,并且可以查看每个跟踪请求占总跟踪时间的百分比。
3.2 搭建Zipkin服务
在父工程中新增zipkin_server
微服务模块, 创建过程和其他微服务一样.
在zipkin微服务中导入zipkin依赖
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.9.4</version>
<!--排除-->
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.9.4</version>
</dependency>
application.yml添加配置信息
server:
port: 9041
spring:
application:
name: zipkin-server
# 去除控制台异常
management:
metrics:
web:
server:
auto-time-requests: false
编写启动类 , 启动类上添加@EnableZipkinServer
注解
// zipkin服务的启动类
@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class);
}
}
3.3 其他应用整合Zipkin
修改网关及服务消费者,生产者所有微服务,让它们注册到Zipkin中,以便让这些微服务产生的日志能发送被Zipkin收集到.
网关微服务, 电影微服务和用户微服务
需要做如下修改.
导入zipkin启动依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
因为zipkin启动依赖
已经包含了spring cloud sleuth
, 所以要删除之前的spring cloud sleuth依赖.
网关微服务, 电影微服务和用户微服务
的application.yml添加zipkin注册配置
spring:
zipkin:
base-url: http://127.0.0.1:9041
sender:
type: web
sleuth:
sampler:
probability: 1 # 采样率值介于 0 到 1 之间,1 则表示全部采集
3.4 Zipkin日志采集
启动zipkin微服务, 网关微服务, 电影微服务和用户微服务
, 访问http://localhost:9004/microservice-movie/movie/order5
.
然后查看zipkin控制台, http://localhost:9041/zipkin/
链路追踪过程
依赖分析
3.5 Zipkin下载
上面是通过搭建Zipkin_Server服务的方式, 整合到其他微服务应用中提供链路追踪的功能的. 但新版本已经提供了开箱即用的jar包给我们使用, 不再需要我们自己搭建Zipkin服务了.
SpringCloud从F版起已不需要自己构建Zipkin Server了,只需调用jar包即可
启动zipkin
java -jar zipkin-server-2.22.1-exec.jar
请求http://localhost/consumer/feign/payment/get/1
, 查看控制台日志.
服务提供方日志, traceId为 f9a6abe76680949d
服务消费方日志, traceId 为 f9a6abe76680949d
, 与上面的一样.
一条链路通过Trace Id唯一标识,Span标识发起的请求信息,各span通过parent id 关联起来
进入zipkin控制台查看. http://localhost:9411/zipkin/
, 查询到刚刚请求的链路追踪记录.
点击show
, 查看链路追踪详情. traceId也是 f9a6abe76680949d
, 实现了日志信息的收集.
再来看依赖分析
, 从消费方consumer请求到服务提供方provider.
点击服务消费方 consumer, 查看依赖详情. 从图中可以看到consumer依赖了provider.
点击服务提供方provider ,查看详情. 可以看到服务提供方provider被消费方consumer依赖.
我这里使用的是比较新的版本
zipkin-server-2.22.1-exec.jar
, 有些老一点的版本可能web页面有一些差异, 但使用方式基本一样.
还是给出一个低版本的对比图. (zipkin-server-2.12.9-exec.jar
)
链路追踪分析图
依赖分析图