YMNNALFT:使用 Micrometer 累积维度指标

工程 | Josh Long | 2021年1月20日 | ...

欢迎来到 您可能不需要另一个库来做这件事 (YMNNALFT) 的另一期!自从 2016 年以来,我花费了大量时间在我的 Spring 提示视频 中阐明(或者至少尝试阐明!)Spring 生态系统中一些更大的机会。然而,今天我以不同的精神来到这里,希望专注于那些做着很棒的事情、有时隐藏着的、小巧的宝石,它们可以让你免于额外的第三方依赖及其带来的复杂性。

凌晨 3 点。您知道您的生产 KPI 指标在哪里吗?您无法改进无法衡量的东西,而指标是其中重要的一部分。没有指标,我们就完全且毫无希望地迷失了,陷入一个不断恶化的死亡行军项目,没有任何改善的迹象或希望!颤抖吧,可怜而悲惨的开发者!没有指标,我们就如同瞎子,这没什么好笑的,所以,这里有一张我女儿可爱的豚鼠凯的照片。

指标为我们提供了一种描述系统特定事实的方法——它让我们能够量化基本数据,这很好,因为有很多东西需要计数和量化。

  • 有多少人点击了“结账”按钮?
  • 有多少人注册了?
  • 对特定端点的请求需要多长时间?
  • 有多少人在遇到错误?
  • 给定请求的平均时间是多少?(或者,更有用的是,给定请求的第 99 个百分位数是多少?
  • 鲍勃,你提交你的 TPS 报告了吗?哦,拜托,鲍勃!我们讨论过这个!你说你会在星期二下班前提交的,你这个无赖!

了解哪些指标需要捕获以及哪些指标无关紧要,这是一种真正的艺术。甚至可以以此为职业!“增长黑客”,有人吗?并非所有指标都是平等的。增长黑客关注指标。产品经理会关注指标。业务会关注指标。您的平台可以关注指标。应该关注指标。为什么不呢?所有数据都可以获取,但您需要一个强大的框架来帮助您。编写代码来检测您的代码并捕获指标只是成功的一半。捕获后,您将希望(需要!)存储和分析这些指标。为此,您将使用一个时间序列数据库——例如 VMware 的 WavefrontPrometheusNetflix AtlasDataDogInstana 等,然后可视化和分析这些数据。您需要一个强大的框架,该框架支持在各种上下文中捕获各种指标(计时器、计数器、直方图、平均值等),然后将这些指标发送到各种时间序列数据库 (TSDB)。

进入 Micrometer。Micrometer 允许您使用供应商中立的接口为您的代码添加维度指标,并在最后一步决定您想使用哪个监控系统。使用 Micrometer 检测您的核心库代码,允许这些库包含在将指标发送到不同后端的应用程序中。Spring Boot 提供了 Actuator 模块来支持捕获和观察应用程序的不同方面。它具有应用程序运行状况、线程转储和无数其他内容的端点。它有一个端点 /actuator/metrics,它依赖于 Micrometer,让您可以一览您的 Spring Boot 应用程序捕获的指标,而不管您是否也将其发布到 TSDB。

请记住,Spring 依赖于 Micrometer,但 Micrometer 不依赖于 Spring。许多库使用 Micrometer SPI 自行检测。您只需添加与 TSDB 的集成即可。以下是一些使用 Micrometer 发送指标的第三方库:Javalin、HikariCP、RabbitMQ Java 客户端、Redisson、Brave 分布式跟踪客户端、Netflix Spinnaker、基于 Netty 的非阻塞 Armeria 框架、Alibaba Nacos 客户端、Apache Geode、Microsoft Azure Spring Boot 集成、Resilience4J、Playtika Feign 客户端、Openrewrite、Apache Camel、Couchbase Java DCP 客户端,以及其他数百个库。哦,我是否提到 Spring 生态系统中的无数模块也支持它?是的,Micrometer 确实无处不在

我们当然正在使用 Spring,因此只需将 Spring Boot Actuator 模块添加到构建中即可。如果要支持特定的 TSBD,则必须引入该特定集成的特定模块。一些 Micrometer 集成也附带完整的 Spring Boot 集成,因此,如果您愿意,可以使用它们来代替直接的 Micrometer 集成。VMware Wavefront 就是这样一个 TSDB,它与 Spring Boot 具有广泛而丰富的集成,因此我将在此处引入该超集集成。

让我们来看一个简单的服务。

您需要以下依赖项。

  • Spring Initializr 上使用 Actuator - org.springframework.boot : spring-boot-starter-actuator

  • Spring Initializr 上使用 Wavefront - com.wavefront : wavefront-spring-boot-starter

在此示例中,我为当天咖啡消费量的统计数据创建了两个计数器指标。我向数据添加了一个额外的维度:咖啡是否含咖啡因。

这是代码

package bootiful.metrics;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
public class BootifulApplication {

	public static void main(String[] args) {
		System.setProperty("spring.profiles.active", "metrics");
		SpringApplication.run(BootifulApplication.class, args);
	}

	@Bean
	ApplicationListener<ApplicationReadyEvent> ready(MeterRegistry registry) {
		return event -> {

			// https://127.0.0.1:8080/actuator/metrics/coffees
			String metricsKey = "coffees";
			Counter decaffeinated = registry.counter(metricsKey, "caffeine", "false");
			Counter caffeinated = registry.counter(metricsKey, "caffeine", "true");

			for (int i = 0; i < (int) (Math.random() * 10); i++)
				caffeinated.increment();

			for (int i = 0; i < (int) (Math.random() * 10); i++)
				decaffeinated.increment();

			System.out.println("caffeinated: " + caffeinated.count());
			System.out.println("decaffeinated: " + decaffeinated.count());

			// https://127.0.0.1:8080/actuator/metrics/message-print
			Timer timer = registry.timer("message-print");

			for (int i = 0; i < 10; i++)
				timer.record(Duration.ofMillis((long) (Math.random() * (10 * 1000))));

			System.out.println("message-print: " + timer.totalTime(TimeUnit.SECONDS));
		};
	}

}

这是我放入 application.properties 中的内容

spring.main.web-application-type=reactive
management.endpoints.web.exposure.include=*
management.endpoint.metrics.enabled=true

在本系列的大多数条目中,我都会提到所讨论库的可能替代方案。我不想在这里这样做,因为我还没有真正找到任何接近 Micrometer 的东西,如果我说有,那是不诚实的。Micrometer 是一个更好的解决方案。您会发现的大多数其他指标框架要么无法与 Micrometer 集成到那么多的解决方案中,要么更糟糕的是,不支持维度指标。维度指标指的是附加了各种属性(维度)的指标数据。这些属性可能包括与持续时间相关的属性(开始和停止时间)、ID、附加到客户端上下文的元数据、请求的区域、有关客户端的信息、有关正在调用的端点的信息、主机、状态代码等。此详细程度允许深入分析和查询。维度指标意味着更容易捕获指标,并且以后更容易以意想不到的方式深入了解这些指标。双赢!

您喜欢这种快速浏览宝石的方式吗?您学到了什么?与往常一样,我渴望听到您的反馈,因此请在 Twitter (@starbuxman) 上发表您的意见!我将带着 YMNNALFT 的另一期回来,所以请务必不要错过。

获取 Spring 时事通讯

与 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获得支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部