对于一个大型的微服务架构系统,会有哪些常见问题?
如何串联调用链,快速定位问题?
如何厘清微服务之间的依赖关系?
如何进行各个服务接口的性能分折?
如何跟踪业务流的处理?
spring Cloud Sleuth为 spring Cloud提供了分布式跟踪的解决方案,它大量借用了Google Dapper、 Twitter Zipkin和 Apache HTrace的设计,先来了解一下 Sleuth的术语, Sleuth借用了 Dapper的术语。
span(跨度):基本工作单元。 span用一个64位的id唯一标识。除ID外,span还包含其他数据,例如描述、时间戳事件、键值对的注解(标签), spanID、span父 ID等。 span被启动和停止时,记录了时间信息。初始化 span被称为"rootspan",该 span的 id和 trace的 ID相等。
trace(跟踪):一组共享"rootspan"的 span组成的树状结构称为 traceo trac也用一个64位的 ID唯一标识, trace中的所有 span都共享该 trace的 ID
annotation(标注): annotation用来记录事件的存在,其中,核心annotation用来定义请求的开始和结束。
CS( Client sent客户端发送):客户端发起一个请求,该 annotation描述了span的开 始。
SR( server Received服务器端接收):服务器端获得请求并准备处理它。如果用 SR减去 CS时间戳,就能得到网络延迟。)
SS( server sent服务器端发送):该 annotation表明完成请求处理(当响应发回客户端时)。如果用 SS减去 SR时间戳,就能得到服务器端处理请求所需的时间。
CR( Client Received客户端接收): span结束的标识。客户端成功接收到服务器端的响应。如果 CR减去 CS时间戳,就能得到从客户端发送请求到服务器响应的所需的时间
Spring Cloud Sleuth可以追踪10种类型的组件:async、Hystrix,messaging,websocket,rxjava,scheduling,web(Spring MVC Controller,Servlet),webclient(Spring RestTemplate)、Feign、Zuul。
我们先来看一下官方给出的图
图片详细讲了我们上文所说的概念在调用链中 处于什么状态以及改变
Zipkin是 Twitter开源的分布式跟踪系统,基于 Dapper的论文设计而来。它的主要功能是收集系统的时序数据,从而追踪微服务架构的系统延时等问题。 Zipkin还提供了一个非常友好的界面,来帮助分析追踪数据。
因为sleuth对于分布式链路的跟踪仅仅是一些数据的记录, 这些数据我们人为来读取和处理难免会太麻烦了,所以我们一般吧这种数据上交给Zipkin Server 来统一处理。
我们新建一个项目zikpin-server,然后引入依赖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">
<parent>
<artifactId>springcloud</artifactId>
<groupId>com.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zikpin_server</artifactId>
<dependencies>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</project>
启动类:
@SpringBootApplication
@EnableZipkinServer
public class ZikpinServerApp {
public static void main(String[] args) {
SpringApplication.run(ZikpinServerApp.class);
}
}
application.yml
server:
port: 6070
management:
metrics:
web:
server:
autoTimeRequests: false
这里有一个问题,就是zipkin2.7.x以后便不支持自定义服务器。需要使用官方的版本或者Docker 。但是如果还是要使用的话就得加上这个配置,就是怎么说呢,非要自己自定义服务器呢那就是出了问题官方不负责。
好了,我们启动一下项目
上面这些信息我就不用解释了吧,大家都是做开发的,一些查询条件判断而已。
现在点击 Find Traces是没有数据的,所以接着做吧。
我们拿user和power项目来玩吧。首先 我们需要依赖sleuth 和 sleuth与zipkin的整合依赖:
在两个项目都需要加这个依赖的。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
然后配置文件:也是两个都加
spring:
application:
name: server-user #此实例注册到Eureka服务端的name
zipkin:
base-url: http://localhost:6070
sleuth:
sampler:
probability: 1.0
uri就是zikpin的地址,然后probability是抓多少数据,默认是0.1,这里我们数据比较少就全抓取了。
然后我们启动一下 eureka3000,user,power,zikpin-server。
请求 http://localhost:6001/getFeignPower 一下。
然后点击 find traces,发现多了一个这个。
我们点进去看看
这就是我们整个链路的请求信息。
我们再来看一个失败的,我们吧power服务停掉,然后稍微等等,就是等eureka把power服务踢出去后请求一下 http://localhost:6001/getFeignPower。然后 再刷新一下页面 http://localhost:6070/zipkin/ 。如下:
点进去看看:
这个时间长是因为他需要多次尝试访问power,但是power是停掉的。
点进去看看详细信息,然后收的是访问这个地址 超时了。停掉肯定是超时的哈哈哈哈。
其实还有很多其他详细的信息,比如
太多了,这个就需要各位自己去测试数据啦。
刚刚我们介绍了如何把分布式链路调用信息上传到 zipkin server 但是 有一个问题:
当zipkin重启后我们的分布式链路数据全部清空了。
因为zipkin server 默认数据是存储在内存当中, 所以当你服务重启之后内存自然而然也就清空了。
我们这里借用ES来做数据持久化, 当然 还可以用ELK来做, 我们这里演示ES
关于Elasticsearch 具体的介绍 我们本文暂时不讨论, 不知道的可以把他当作mysql存储。
Elasticsearch 下载地址:https://www.elastic.co/cn/downloads/elasticsearch
下载完是个压缩包 解压出来 打开bin目录 找到elasticsearch.bat文件启动
等他启动一会儿然后在页面上输入localhost:9200看见如下信息说明Elasticsearch 启动好了。
接下来我们再zikpin-server项目中添加依赖:
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
<version>2.3.1</version>
</dependency>
然后改一下配置文件:
server:
port: 6070
management:
metrics:
web:
server:
autoTimeRequests: false
zipkin:
storage:
type: elasticsearch
elasticsearch:
cluster: elasticsearch
hosts: http://localhost:9200
index: zipkin
好了,重启一下项目,然后访问几次user那边,再重启zikpin-server,你就会发现以前的数据还是会显示在这里,看吧:
我早上访问的数据还在。
好了布式链路跟踪就算讲完了,最开始提出的几个问题,一个页面直接就解决了,这个可以自己试着解答一下那几个问题吧。到此,微服务这边暂时估计不会更新了,其他组件我玩的比较少,写出来怕误人子弟,等我有一定理解后再来写吧。接下来会更新docker的使用。