Spring cloud Zipkin 服务跟踪
版本:
Spring Cloud : Greenwich.RELEASE
spring-boot : 2.1.6.RELEASE
JDK 1.8
前言
在微服务中,很多的服务之间互相调用,也有从一个服务一直请求好几个服务,到最后一个服务,整个过程会很复杂,如果出故障的时候排查或者优化时工作量就会比较大。如果能准确的跟踪每一个网络请求运行流程,获取每个服务请求访问情况,延迟多少,耗费时间等,这样子对于我们分析系统性能,排查问题有很大的帮助,对此,微服务服务跟踪就产生了。
什么是 Zipkin
Zipkin 是一个可以采集并且跟踪分布式系统中请求数据的组件,可以为开发者采集某个请求在多个微服务之间的追踪数据,并以可视化的形式呈现出来,让开发者可以更加直观地了解到请求在各个微服务中所耗费的时间等信息。
ZipKin 组件包括两部分:Zipkin Server 和 Zipkin Client,服务端用来采集微服务之间的追踪数据,再通过客户端完成数据的生成和展示,Spring Cloud 为服务跟踪提供了解决方案,Spring Cloud Sleuth 集成了 Zipkin 组件。
Zipkin
Zipkin是Twitter的一个开源项目,它基于Google Dapper实现。我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的REST API接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的API接口之外,它也提供了方便的UI组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。
详细可以看
SpringCloudSleuth 简介
通过 SpringCloud 来构建微服务架构,我们可以通过 SpringCloudSleuth 实现分布式追踪,它集成了 Zipkin。
Sleuth 术语
-
span(跨度):基本工作单元。例如,在一个新建的 span 中发送一个 RPC 等同于发送一个回应请求给 RPC,span 通过一个 64 位 ID 唯一标识,trace 以另一个 64 位 ID 表示,span 还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span 的 ID,以及进度 ID(通常是 IP 地址)。span 在不断的启动和停止,同时记录了时间信息,当你创建了一个 span,你必须在未来的某个时刻停止它。
-
trace(追踪):一组共享“root span”的 span 组成的树状结构成为 trace。trace 也用一个 64 位的 ID 唯一标识,trace 中的所有 span 都共享该 trace 的 ID。
annotation(标注):用来及时记录一个事件的存在,一些核心 annotations 用来定义一个请求的开始和结束。
CS,即 Client Sent,客户端发起一个请求,这个 annotion 描述了这个 span 的开始。SR,即 Server Received,服务端获得请求并准备开始处理它,如果将其 SR 减去 CS 时间戳便可得到网络延迟。
SS,即 Server Sent,注解表明请求处理的完成(当请求返回客户端),如果 SS 减去 SR 时间戳便可得到服务端需要的处理请求时间。
CR,即 Client Received,表明 span 的结束,客户端成功接收到服务端的回复,如果 CR 减去 CS 时间戳便可得到客户端从服务端获取回复的所有所需时间。
下图演示了请求依次经过 SERVICE1 -> SERVICE2 -> SERVICE3 -> SERVICE4 时,span、trace、annotation 的变化:
简单的链路追踪实现
要实现完整的服务器链路,需要有服务端和客户端两个服务
注意
:
在 Spring Boot 2.0 以前,我们需要自己实现 Zipkin 服务端,从 Spring Boot 2.0 以后,其推出了官方 Zipkin 服务端,我们只需要下载服务端 jar 包,放到服务器上,启动即可。
这里我们演示导入依赖
新建服务端 zipkin
spring:
application:
name: zipkin
# 解决Zipkin启动The bean 'characterEncodingFilter', defined in
main:
allow-bean-definition-overriding: true
server:
port: 9411
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
management:
metrics:
web:
# 解决Zipkin报错IllegalArgumentException: Prometheus requires that all meters
server:
auto-time-requests: false
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin</artifactId>
<version>2.9.4</version>
</dependency>
<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>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableZipkinServer
public class ZipkinClientApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinClientApplication.class,args);
}
}
@EnableDiscoveryClient 注解表示将其注册到服务中心中
@EnableZipkinServer 表示启动链路追踪服务端
@SpringBootApplication 启动Spring Boot服务
Zipkin 服务端的默认启动端口为 9411,浏览器访问 http://localhost:9411 然后进入 Zipkin 服务端管理界面
然后我们来实现一个客户端
首先是配置文件,将此服务追踪到上面链路追踪服务中心
server:
port: 9001
spring:
application:
name: admin-client
# 链路追踪
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
probability: 1 # 默认是0.1 也就是采样请求10%
spring.zipkin.base-url
用来指定 zipkinServer 的地址
spring.sleutch.sampler.probability
用来指定采样请求的百分比(默认为 0.1,即 10%)
在客户端添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
启动方法
@SpringBootApplication
public class AdminClientApplication {
public static void main(String[] args) {
SpringApplication.run(AdminClientApplication.class, args);
}
}
写一个控制层
@RestController
public class AdminController {
@GetMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "hello " + name + ", this is admin - client";
}
}
然后分别启动服务端和客户端
访问客户端请求地址
打开服务链服务中心管理界面可以看到 刚才请求的一条记录
点击进去可以查看详情
比如服务调用深度,总次数,请求Url 时间 参数 ip地址等等
服务链路追踪的数据都是在内存中,一般情况下这种数据我们肯定是要持久化的
ZipkinServer 支持多种后端存储数据,如 MySQL、ElasticSearch、Cassandra 等。
之后再研究。。。