前言
在第四篇和第五篇中提到一个叫关联 id的东西,用这个东西来将所有请求串起来,用来清晰的记录调用过程,以便以微服务的问题调试。
微服务虽然能够将单体软件系统分解为更小的、更易于管理的小系统。但是这种特性是需要付出代价的。其中之一就是----调试困难。所以需要有一种办法能够将所有服务产生的消息聚合起来,方便的获取某一次用户请求的全部日志信息。本篇只解决将请求串起来这个问题,日志聚合需要对应的日志平台配合,这里不做讨论(其实就是将日志全部手机放到一个地方(比如 es),再进行查询)。
(PS:写这篇的时候突然发现,前面那种实现关联 id 方法是错误的,学习《spring 微服务实战》过程中看到了不少错误,单大都不是很重要的,唯独关联 id 的那部分问题挺大。书上的实现是在每个服务中增加一个过滤器,提取入站请求中的关联 id,然后存到 ThreadLocal 中,然后给服务调用类 Ribbon 加一个过滤器:用于从 ThreadLocal 中提取出关联 id 然后加入到请求的 header 中。这里的问题是前面的过滤器所在的线程和后面服务调用的线程不是同一个线程,也就无法用 ThreadLocal 来进行数据保存。在 Feign 请求的过程中是获取不到保存的值的)
集成 Spring Cloud Sleuth
什么是 Spring Cloud Sleuth
简单来说 Spring Cloud Sleuth 就是为开发人员实现了前面关联 ID 尝试做的事情,而且做的更好。主要有一下几个功能:
透明地创建并注入一个关联 ID 到服务调用中(如果不存在关联 ID)
管理
关联ID
到出站服务的传播,将关联 iD 自动添加啊到出站调用中将
关联信息
添加到 Spring 的 MDC 日志记录,以便生成的关联ID
由 Spring Boot 默认的 SL4J 和 Logback 实现自动记录
怎么用
用法很简单,只需在要用的服务中引入 SpringCloudSleuth
依赖即可,代码如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId></dependency>
然后就会发现引入该依赖的服务日志打印语句中都会多一些数据,结构如下:
2019-02-28 11:03:02 [ERROR] [server Name,trace ID,span ID,isSendData]...
其中各项意义如下:
server Name:默认情况下使用
spring.applicataion.name
。trace ID:跟踪 ID,相当于关联 ID。整个微服务调用过程的唯一编号。
span ID: 跨度 ID。表示某个服务过程中的唯一 ID,比如在服务 A 中打印的日志跨度 ID 都是一样的。
isSendData: 是否发送数据给 Zipkin。可配置是否将数据发给 Zipkin,毕竟不是所有日志打印都是要收集的。
使用过于简单,因此不提供代码,自己引入依赖就能看到效果,无需任何配置。
尾声
微服务的分布式跟踪是一个很复杂的过程,上面所说的仅仅只是实现了给日志输入打上标记,让微服务调用能够串在一起。之后还有一个很重要的过程是日志收集和分析。后面如果有时间,可能会继续更新完成日志聚合。