- 内容提要
- 译者序
- 前言
- 第 1 章 欢迎迈入云世界,Spring
- 第 2 章 使用 Spring Boot 构建微服务
- 第 3 章 使用 Spring Cloud 配置服务器控制配置
- 第 4 章 服务发现
- 第 5 章 使用 Spring Cloud 和 Netflix Hystrix 的客户端弹性模式
- 第 6 章 使用 Spring Cloud 和 Zuul 进行服务路由
- 第 7 章 保护微服务
- 第 8 章 使用 Spring Cloud Stream 的事件驱动架构
- 第 9 章 使用 Spring Cloud Sleuth 和 Zipkin 进行分布式跟踪
- 第 10 章 部署微服务
- 附录 A 在桌面运行云服务
- 附录 B OAuth2 授权类型
9.1 Spring Cloud Sleuth 与关联 ID
在第 5 章和第 6 章中,我们介绍了关联 ID 的概念。关联 ID 是一个随机生成的、唯一的数字或字符串,它在事务启动时分配给一个事务。当事务流过多个服务时,关联 ID 从一个服务调用传播到另一个服务调用。在第 6 章的上下文中,我们使用 Zuul 过滤器检查了所有传入的 HTTP 请求,并且在关联 ID 不存在的情况下注入关联 ID。
一旦提供了关联 ID,就可以在每个服务上使用自定义的 Spring HTTP 过滤器,将传入的变量映射到自定义的 UserContext
对象。有了 UserContext
对象,现在可以手动地将关联 ID 添加到日志语句中,或者通过少量工作将关联 ID 直接添加到 Spring 的映射诊断上下文(Mapped Diagnostic Context,MDC)中,从而确保将关联 ID 添加到任何日志语句中。我们还编写了一个 Spring 拦截器,该拦截器通过向出站调用添加关联 ID 到 HTTP 首部中,确保来自服务的所有 HTTP 调用都会传播关联 ID。
对了,我们必须施展 Spring 和 Hystrix 的魔法,以确保持有关联 ID 的父线程的线程上下文被正确地传播到 Hystrix。在最后,这些数量众多的基础设施都是为了某些你希望只有在问题发生时才查看的东西而设置的(使用关联 ID 来跟踪事务中发生了什么)。
幸运的是,Spring Cloud Sleuth 能够为开发人员管理这些代码基础设施并处理复杂的工作。通过添加 Spring Cloud Sleuth 到 Spring 微服务中,开发人员可以:
- 透明地创建并注入一个关联 ID 到服务调用中(如果关联 ID 不存在);
- 管理关联 ID 到出站服务调用的传播,以便将事务的关联 ID 自动添加到出站调用中;
- 将关联信息添加到 Spring 的 MDC 日志记录,以便生成的关联 ID 由 Spring Boot 默认的 SL4J 和 Logback 实现自动记录;
- (可选)将服务调用中的跟踪信息发布到 Zipkin 分布式跟踪平台。
注意
有了 Spring Cloud Sleuth,如果使用 Spring Boot 的日志记录实现,关联 ID 就会自动添加到微服务的日志语句中。
让我们继续,将 Spring Cloud Sleuth 添加到许可证服务和组织服务中。
9.1.1 将 Spring Cloud Sleuth 添加到许可证服务和组织服务中
要在两个服务(许可证和组织)中开始使用 Spring Cloud Sleuth,我们需要在两个服务的 pom.xml 文件中添加一个 Maven 依赖项:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
这个依赖项会拉取 Spring Cloud Sleuth 所需的所有核心库。就这样,一旦这个依赖项被拉进来,服务现在就会完成如下功能。
(1)检查每个传入的 HTTP 服务,并确定调用中是否存在 Spring Cloud Sleuth 跟踪信息。如果 Spring Cloud Sleuth 跟踪数据确实存在,则将捕获传递到微服务的跟踪信息,并将跟踪信息提供给服务以进行日志记录和处理。
(2)将 Spring Cloud Sleuth 跟踪信息添加到 Spring MDC,以便微服务创建的每个日志语句都添加到日志中。
(3)将 Spring Cloud 跟踪信息注入服务发出的每个出站 HTTP 调用以及 Spring 消息传递通道的消息中。
9.1.2 剖析 Spring Cloud Sleuth 跟踪
如果一切创建正确,则在服务应用程序代码中编写的任何日志语句现在都将包含 Spring Cloud Sleuth 跟踪信息。例如,图 9-1 展示了如果要在组织服务上执行 HTTP GET 请求 http://localhost:5555/api/organization/v1/organizations/e254f8c-c442-4ebe-
a82a-e2fc1d1ff78a
,服务将输出什么结果。
图 9-1 Spring Cloud Sleuth 为服务编写的每个日志条目添加了 4 条跟踪信息,这些数据有助于将用户请求的服务调用绑定在一起
Spring Cloud Sleuth 将向每个日志条目添加以下 4 条信息(与图 9-1 中的数字对应)。
(1) 服务的应用程序名称 ——这是创建日志条目时所在的应用程序的名称。在默认情况下,Spring Cloud Sleuth 将应用程序的名称( spring.application.name
)作为在跟踪中写入的名称。
(2) 跟踪 ID(trace ID) ——跟踪 ID 是关联 ID 的等价术语,它是表示整个事务的唯一编号。
(3) 跨度 ID(span ID) ——跨度 ID 是表示整个事务中某一部分的唯一 ID。参与事务的每个服务都将具有自己的跨度 ID。当与 Zipkin 集成来可视化事务时,跨度 ID 尤其重要。
(4) 是否将跟踪数据发送到 Zipkin ——在大容量服务中,生成的跟踪数据量可能是海量的,并且不会增加大量的价值。Spring Cloud Sleuth 让开发人员确定何时以及如何将事务发送给 Zipkin。Spring Cloud Sleuth 跟踪块末尾的 true/false
指示器用于指示是否将跟踪信息发送到 Zipkin。
到目前为止,我们只查看了单个服务调用产生的日志数据。让我们来看看通过 GEThttp://localhost:5555/api/licensing/v1/organizations/e254f8c-c442-4ebe-
a82a-e2fc1d1ff78a/licenses/f3831f8c-c338-4ebe-a82a-e2fc-1d1ff78a
调用许可证服务时会发生什么。记住,许可证服务还必须向组织服务发出调用。图 9-2 展示了来自两个服务调用的日志记录输出。
图 9-2 当一个事务中涉及多个服务时,可以看到它们具有相同的跟踪 ID
查看图 9-2 可以看出许可证服务和组织服务都具有相同的跟踪 ID—— a9e3e1786b74d302
。但是,许可证服务的跨度 ID 是 a9e3e1786b74d302
(与事务 ID 的值相同),而组织服务的跨度 ID 是 3867263ed85ffbf4
。
只需添加一些 POM 的依赖项,我们就已经替换了在第 5 章和第 6 章中构建的所有关联 ID 的基础设施。就我个人而言,在这个世界上,没有什么比用别人的代码代替复杂的、基础设施风格的代码更让我开心的了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论