问题:
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。
在分布式与微服务场景下,我们需要解决如下问题:
在大规模分布式与微服务集群下,如何实时观测系统的整体调用链路情况。
在大规模分布式与微服务集群下,如何快速发现并定位到问题。
在大规模分布式与微服务集群下,如何尽可能精确的判断故障对系统的影响范围与影响程度。
在大规模分布式与微服务集群下,如何尽可能精确的梳理出服务之间的依赖关系,并判断出服务之间的依赖关系是否合理。
在大规模分布式与微服务集群下,如何尽可能精确的分析整个系统调用链路的性能与瓶颈点。
在大规模分布式与微服务集群下,如何尽可能精确的分析系统的存储瓶颈与容量规划。
上述问题就是我们的落地议题答案:
分布式链路追踪技术要解决的问题,分布式链路追踪(Distributed Tracing),就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。
Spring Cloud Sleuth 不适用于 Spring Boot 3.x 及更高版本。Sleuth 将支持的最后一个主要 Spring Boot 版本是 2.x。
Sleuth项目的核心已移至Micrometer Tracing项目,仪器将移至Micrometer 和所有相应的项目(不再所有仪器都将在单个存储库中完成。
行业内成熟的分布式链路追踪解决方案
Micrometer
概述
Micrometer 为最流行的可观测性系统提供了基于检测客户端的简单外观,允许您检测基于 JVM 的应用程序代码,而不会受到供应商的束缚。想想 SLF4J,但为了应用程序的可观测性!Micrometer 记录的数据旨在用于观察、警报和响应环境的当前/最近运行状态。
安装
Micrometer 包含一个带有仪器 SPI 的核心库和一个不将数据导出到任何地方的内存实现、一系列模块以及用于各种监控系统的实现,以及一个测试模块。
要使用 Micrometer,请添加监控系统的依赖关系。
以下示例在 Maven 中添加了 Prometheus:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>${micrometer.version}</version>
</dependency>
通过 Micrometer 的复合仪表注册表(在“概念”中更详细地描述),如果您打算将指标发布到多个监控系统,您可以配置多个注册表实现。
如果您尚未决定使用监控系统,而只想试用检测 SPI,则可以添加依赖 micrometer-core
项并配置 SimpleMeterRegistry
.
快照
每次成功构建 Micrometer main
和维护分支(例如, 1.7.x
)都会发布新的快照版本。您可以通过 repo.spring.io/snapshot
将 Maven 存储库添加到您的构建并使用相应的快照版本(例如 1.8.0-SNAPSHOT
.
里程碑
里程碑版本可用于早期测试目的,不用于生产用途。里程碑版本将发布到 repo.spring.io/milestone。要使用里程碑版本,请将其作为 Maven 存储库包含在构建配置中。里程碑在 GitHub 上标记为“预发布版”,并且版本具有后缀,例如 -M1
或 -RC1
(分别为里程碑 1 或候选版本 1)。
概念
Micrometer 是一个用于基于 JVM 的应用程序的度量指标检测库。它为最流行的监视系统的检测客户端提供了一个简单的外观,使您能够检测基于 JVM 的应用程序代码,而不会受到供应商的束缚。它旨在为您的指标收集活动增加很少甚至没有开销,同时最大限度地提高指标工作的可移植性。
支持的监控系统
Micrometer包含一个带有仪器 SPI 的核心模块、一组包含各种监控系统实现的模块(每个模块称为注册表)和一个测试套件。您需要了解监控系统的三个重要特征:
- 维度。系统是否支持使用标签键/值对扩充指标名称。如果系统不是维度的,则它是分层的,这意味着它仅支持平面指标名称。将指标发布到分层系统时,Micrometer 会展平标签键/值对集,并将它们添加到名称中。
- 速率聚合。在这种情况下,我们指的是在规定的时间间隔内聚合一组样本。某些监控系统希望某些类型的离散样本(如计数)在发布之前由应用程序转换为速率。其他系统希望始终发送累积值。还有一些人对此没有意见。
- 出版。一些系统希望在闲暇时轮询应用程序以获取指标,而另一些系统则希望定期将指标推送到它们。
从一个监测系统到另一个监测系统的期望还有其他更细微的差异,例如它们对基本测量单位(特别是时间)的概念和指标的规范命名约定。Micrometer 可自定义您的指标,以满足每个注册表的这些需求。
Registry 注册表
A Meter
是用于收集有关应用程序的一组度量值(我们单独称为指标)的接口。以Micrometer为单位的Meter是由 创建并保存在 MeterRegistry
.每个受支持的监控系统都有一个实现 MeterRegistry
。注册表的创建方式因每个实现而异。
Micrometer包括一个 SimpleMeterRegistry
,它将每个仪表的最新值保存在内存中,并且不会将数据导出到任何地方。如果您还没有首选的监控系统,则可以使用简单的注册表开始使用指标:
MeterRegistry registry = new SimpleMeterRegistry();
复合注册表
Micrometer提供了一个 CompositeMeterRegistry
可以添加多个注册表的功能,允许您同时将指标发布到多个监控系统:
CompositeMeterRegistry composite = new CompositeMeterRegistry();
Counter compositeCounter = composite.counter("counter");
compositeCounter.increment();
SimpleMeterRegistry simple = new SimpleMeterRegistry();
composite.add(simple);
compositeCounter.increment();
-
增量是 NOOP'd,直到复合中有注册表。此时,计数器的计数仍生成 0。
-
名为
counter
的计数器注册到简单注册表中。 -
简单注册表计数器以及复合中任何其他注册表的计数器将递增。
Meters
Micrometer支持一组 Meter
基元,包括 Timer
、 Counter
、 、 Gauge
、 DistributionSummary
LongTaskTimer
FunctionCounter
FunctionTimer
、 和 TimeGauge
。不同的计量类型会导致不同数量的时间序列指标。例如,虽然有一个指标表示 Gauge
,但 a Timer
同时测量计时事件的计数和所有计时事件的总时间。
仪表由其名称和尺寸唯一标识。我们交替使用术语“尺寸”和“标签”,而千分尺接口 Tag
只是因为它更短。作为一般规则,应该可以使用该名称作为枢轴。维度允许对特定的命名指标进行切片,以便对数据进行深入钻取和推理。这意味着,如果仅选择名称,则可以使用其他维度和有关所显示值的原因向下钻取。
ZipKin
在本节中,我们将逐步介绍如何构建和启动 Zipkin 实例,以便在本地检出 Zipkin。有三种选择:使用 Java、Docker 或从源代码运行。
如果您熟悉 Docker,这是首选的启动方法。如果您不熟悉 Docker,请尝试通过 Java 或从源代码运行。
如果您安装了 Java 17 或更高版本,那么最快的入门方法是将最新版本作为独立的可执行 jar 获取:
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
运行