> For the complete documentation index, see [llms.txt](https://jun-wang.gitbook.io/learnjava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/spring/springcloud/springcloudsleuth.md).

# SpringCloudSleuth

当搭建的微服务越来越复杂的时候，通常一个客户端发起的请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果，这样就产生了一条复杂的分布式服务调用链路，在每条链路中，任何一个依赖的服务出现延时或者错误都可能引起请求最后的失败。这个时候对于每一个请求，全链路调用的跟踪就变得越来越重要，通过实现对请求调用的跟踪可以帮助我们快速发现错误根源以及监控分析每条请求链路上的性能瓶颈等。

针对上述问题，Spring Cloud Sleuth提供了一整套完整的解决方案。

## 主要元数据

Sleuth有4个重要元素，在我们使用Sleuth的时候会得到如下信息：

```shell
[feign-consumer,b34fcb26d9f6c28a,b34fcb26d9f6c28a,false]
```

* 第一个值：应用名称
* 第二个值：TraceID，用来标志一条请求链路。一条请求链路中包含一个TraceID，多个SpanID。
* 第三个值：SpanID，表示一个基本的工作单元，比如发送一个http请求。
* 第四个值：表示是否要将该信息输出到Zipkin等服务中来收集和展示。

## 跟踪原理

* 为了实现跟踪请求，当请求发送到分布式系统的入口端点时，创建一个唯一的标志TraceID，在内部流转的时候保持不变，直到返回给请求方。
* 为了统计各处理单元的时间延迟，当请求达到各组件时，或是处理逻辑到达某个状态时，也通过唯一标志SpanID标记开始、过程以及结束。除了统计时间还可以包含其他元数据，比如事件名称、请求信息等。
* 在请求传递中，Sleuth会在http请求头header加一些实现跟踪的重要信息：
  * X-B3-TraceId：TraceID
  * X-B3-SpanId：SpanID
  * X-B3-ParentSpanId：前一个工作单元的SpanID，第一个工作单元此值为空
  * X-B3-Sampled：是否被抽样输出的标志，1-需要被输出，0-不需要被输出
  * X-Span-Name：工作单元的名称

Sleuth基本能够跟踪各个通信通道：

* Spring Cloud Stream绑定器实现的消息中间件，RabbitMQ、Kafka等。
* 通过Zuul代理传递的请求。
* 通过RestTemplate发起的请求。

## 整合Zipkin

### Zipkin组件

* Controller：收集器组件，处理外部系统发来的跟踪信息，转化为Zikpin内部处理的Span格式，以支持后续的存储、分析、展示等功能；
* Storage：存储组件，它主要处理收集到的跟踪信息，默认存储在内存，也可以修改策略存储到数据库中；
* RESTful API：API组件，用来提供外部访问接口，比如给客户端展示跟踪信息，或是外接系统访问以实现监控等；
* WEB UI：UI组件，基于API组件实现的上层应用。通过UI组件，用户可以方便而又直观的查询和分析跟踪信息。
