Spring Cloud Sleuth 简述
当开发者进行微服务架构开发时,通常会根据业务来划分微服务,各业务之间通过 REST 进行调用。对于一个用户的请求,往往需要多个微服务协同才能完成处理并形成最后结果返回给用户。在这个过程中,用户请求所经过的每一个微服务都会形成一条复杂的、分布式的服务调用链路,链路中的任何一环出现问题或者网络超时,都会导致用户请求的失败。当出现这种情况时如何对整个请求处理链进行分析,在运维过程中是非常重要的一环。
Spring Cloud Sleuth 为微服务之间调用提供了一套完整的服务链路跟踪解决方案。通过 Sleuth 可以很清楚地了解到一个用户请求经过了哪些微服务,每个微服务处理花费了多长时间,从而让开发者可以方便地理清各微服务间的调用关系。此外,通过 Spring Cloud Sleuth 可以帮助开发者做以下几件事。
耗时分析:通过 Sleuth 可以很方便地了解到每个采样请求的耗时,从而分析出哪些微服务调用比较耗时。
可视化错误:对于程序未捕捉的异常,可以在集成 Zipkin 服务界面上看到。
链路优化:通过 Sleuth 可以轻松识别出调用比较频繁的微服务,开发者可以针对这些微服务实施相应的优化措施。
在基于微服务的架构中,微服务之间是通过 HTTP 协议(REST)方式进行通信的,所以 Spring Cloud Sleuth 在实现时也是基于 HTTP 的,通过在 HTTP 中的 header(头部)添加跟踪所需要的信息,使得在不影响现有业务的基础上完成对服务请求的追踪。总的来说,Sleuth 的实现原理可以总结如下。
服务追踪:对于同一个用户请求,认为是同一条链路,并赋值一个相同的 TraceID,在后续中通过该标识就可以在多个微服务之间找到完整的处理链路。
服务监控:对于链路上的每一个微服务处理,Sleuth 会再生成一个独立的 SpanID,同时记录请求到达时间和离开时间等信息,以作为用户请求追踪的依据,从而判断每一个微服务的处理效率。
其中一些主要术语解释如下:
Span:是 Sleuth 中最基本的工作单元。微服务发起一次请求就是一个新 Span。Span 使用唯一的、长度为 64 位的 ID 作为标识。在 Span 中可以带有其他数据,如描述、时间戳、键值对、起始 Span 的 ID 等数据。Span 有起始和结束,可以用于跟踪服务处理时间信息。Span 一般都是成对出现,因为有始必有终,所以一旦创建了一个 Span,就必须在未来某个时间点结束它。
Trace:一次用户请求所涉及的所有 Span 的集合,采用树形结构进行管理。
Annotation:用于记录时间信息,包含了以下几项。
✧ cs:客户端发送(Client Sent),表示一个 Span 的起始点。
✧ sr:服务端接收(Server Received),表示服务端接收到请求并开始处理。如果减去 cs 的时间戳,则可以计算出网络传输耗时。
✧ ss:服务端完成请求处理,应答信息被发回客户端(Server Sent)。通过减去 sr 的时间戳,可以计算出服务端处理请求的耗时。
✧ cr:客户端接收(Client Received),标志着一个 Span 生命周期的结束,客户端成功地接收到服务端的应答信息。如果减去 cs 的时间戳,则可以计算出整个请求的响应耗时。
在生成环境中,由于业务量比较大,所产生的追踪数据可能会非常大,如果全部采集,一是对业务有一定影响,二是存储压力也会比较大,所以采样就变得很重要了。一般来说,开发者不需要记录每一个追踪数据,通过合适的采样就可以完成对生成环境的监控分析。
Sleuth 为此提供了一个 Sampler 策略,可以通过该策略来控制采样算法。Sleuth 默认采样算法的实现是水塘抽样(Reservoir sampling)算法。水塘抽样算法是指对给定一个长度很大或者未知的数据流(只能对该数据流中的数据访问一次)进行抽样,使得数据流中的所有数据被选中的概率相等,具体的实现类是 PercentageBasedSampler,默认的采样比例为 0.1(即 10%)。我们可以在项目配置文件中通过 spring.sleuth.sampler.percentage 属性进行更改,所设置的值需要介于 0.0~1.0 之间。0.0 表示不采样,1.0 则表示全部采样。
版权声明: 本文为 InfoQ 作者【阿泽🧸】的原创文章。
原文链接:【http://xie.infoq.cn/article/344db222d6fac67673e1dcc11】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论