在 Quarkus 应用程序中收集指标
前言 复制链接链接已复制到粘贴板!
作为应用程序开发人员,您可以使用 Micrometer 收集指标,以提高 Quarkus 应用程序的性能。
先决条件
已安装 OpenJDK (JDK) 11,以及
JAVA_HOME环境变量指定的 Java SDK 的位置。- 登录到红帽客户门户网站,从 Software Downloads 页面下载 Red Hat Open JDK 版本。
- 已安装 Apache Maven 3.6.2 或更高版本。Maven 可从 Apache Maven 项目网站 获得。
对红帽文档提供反馈 复制链接链接已复制到粘贴板!
我们非常感谢您对我们的技术内容提供反馈,并鼓励您告诉我们您的想法。如果您想添加评论,提供见解、纠正拼写错误甚至询问问题,您可以在文档中直接这样做。
您必须有一个红帽帐户并登录到客户门户网站。
要从客户门户网站提交文档反馈,请执行以下操作:
- 选择 Multi-page HTML 格式。
- 点文档右上角的 反馈 按钮。
- 突出显示您要提供反馈的文本部分。
- 点高亮文本旁的添加反馈对话框。
- 在页面右侧的文本框中输入您的反馈,然后单击 Submit。
每次提交反馈时,我们都会自动创建跟踪问题。打开在点 Submit 后显示的链接,并开始监视问题或添加更多注释。
感谢您的宝贵反馈。
使开源包含更多 复制链接链接已复制到粘贴板!
红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。有关更多详情,请参阅我们的首席技术官 Chris Wright 提供的消息。
第 1 章 Quarkus 应用程序的指标集合 复制链接链接已复制到粘贴板!
指标是应用程序的特定方面量量量,用于观察趋势和行为。单个测量会定期收集,每个观察到的数字值都由字符串键以及附加(可选)标签或标签标识。
这些键值对随后附加到时间序列中:一个数据点序列随着时间进行索引。捕获和分析指标可帮助您在升级前发现潜在的问题和异常问题,并导致更严重的问题。
指标不能用于诊断或问题确定。视觉化工具聚合各个测量,以提供趋势的视觉化。您需要识别观察问题的原因的具体上下文在聚合指标数据中找不到;您需要更详细的 trace 或日志数据以确定问题或根本原因分析。
您可以使用 Micrometer 库或 SmallRye Metrics 规格来收集运行时和应用程序指标:
- Micrometer 为已知的监控系统提供了一个简单的传真客户端。Quarkus 对 Prometheus 的 Micrometer 对,以帮助您监控和管理应用程序。
- smallrye Metrics 是 MicroProfile Metrics 规范的实现,提供 Prometheus 兼容指标端点。
Micrometer 扩展是在 Quarkus 中收集应用程序和运行时指标的建议方法,并提供以下功能:
- 维度指标 - 计时器、gauges、计数器、分发摘要和长期任务计时器的供应商中立接口,具有维度的监控系统,允许在其维度监控系统之间有效访问特定命名指标。
-
预配置绑定 - 缓存开箱即用的检测、类加载程序、垃圾回收、处理器利用率、线程池和 HTTP 流量。其他扩展,如
hibernate-orm和mongodb-client,在启用时自动提供额外的绑定。
第 2 章 在 Quarkus 应用程序中公开指标 复制链接链接已复制到粘贴板!
使用 微 标题扩展在 Quarkus 1.11 中启用指标。启用后,微 主题扩展收集的所有指标的实时值会使用 /q/metrics 端点来查看。默认情况下,此端点仅以纯文本方式响应。
流程
添加
quarkus-micrometer-registry-prometheus扩展作为应用程序的依赖项:./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-micrometer-registry-prometheus"此命令将以下依赖项添加到
pom.xml中:pom.xml
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency>输入以下命令在终端显示收集的指标:
curl http://localhost:8080/q/metrics(可选)要使用 Micrometer 扩展来启用 JSON 格式的指标集合,请将以下行添加到
src/main/resources/application.properties文件中:quarkus.micrometer.export.json.enabled=true-
保存对
application.properties文件的更改。 使用以下命令以 JSON 格式查看指标:
curl -i -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:8080/q/metrics
第 3 章 Quarkus 应用程序的自定义指标 复制链接链接已复制到粘贴板!
Micrometer 提供了一个 API,允许您构建自己的自定义指标。监控系统支持的最常见的分段类型包括 Ggauges、计数器和总结。以下小节构建了一个示例端点,并使用这些基本测量类型观察端点行为。
要注册游戏,您需要对 MeterRegistry 的引用,该引用由 Micrometer 扩展进行配置和维护。MeterRegistry 可以注入到应用程序中,如下所示:
package org.acme.micrometer;
import io.micrometer.core.instrument.MeterRegistry;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/")
@Produces("text/plain")
public class ExampleResource {
private final MeterRegistry registry;
ExampleResource(MeterRegistry registry) {
this.registry = registry;
}
}
Micrometer 具有惯例,例如,必须创建分段,并使用点分隔段,例如 a.name.like. this。然后 Micrometer 将该名称转换为所选 registry 首选格式。Prometheus 使用下划线,这意味着之前的名称在 Prometheus 格式的指标输出中显示为 a_name_like_ this。
Micrometer 在唯一指标标识符和标签组合和特定分段实例之间维护内部映射。使用 寄存器、计数器 或其他方法递增计数器或记录值不会创建温度的新实例,除非之前没有看到标识符和标签值的组合。
gauges
Guguges 测量一个可随时间增加或减少的值,比如付款的速度。在监控缓存或集合的统计信息时,Guguges 很有用。考虑以下简单示例来观察列表的大小:
LinkedList<Long> list = new LinkedList<>();
// Update the constructor to create the gauge
ExampleResource(MeterRegistry registry) {
this.registry = registry;
registry.gaugeCollectionSize("example.list.size", Tags.empty(), list);
}
@GET
@Path("gauge/{number}")
public Long checkListSize(@PathParam("number") long number) {
if (number == 2 || number % 2 == 0) {
// add even numbers to the list
list.add(number);
} else {
// remove items from the list for odd numbers
try {
number = list.removeFirst();
} catch (NoSuchElementException nse) {
number = 0;
}
}
return number;
}
使用 Prometheus 时,创建的 gauge 的值并在 Prometheus 端点被访问时观察到列表的大小。务必要注意,gaug 被抽样而不是设置,没有记录与 gauge 关联的值如何在测量之间有所变化。
Micrometer 为创建 gauges 提供了一些额外的机制。请注意,micrometer 不会创建对默认观察到的对象的强引用。根据 registry,micrometer 可以省略 gauges 来观察整个垃圾回收的对象,或使用 NaN (不是数字)作为观察到的值。
永远不会计算您可以计算的任何内容。gauges 可能比计数器更低。如果您要计算量(因为值始终递增),请使用计数器。
计数器
计数器用于测量仅增加的值。在以下示例中,您将计算测试数字的次数,以查看它是主数:
@GET
@Path("prime/{number}")
public String checkIfPrime(@PathParam("number") long number) {
if (number < 1) {
return "Only natural numbers can be prime numbers.";
}
if (number == 1 || number == 2 || number % 2 == 0) {
return number + " is not prime.";
}
if ( testPrimeNumber(number) ) {
return number + " is prime.";
} else {
return number + " is not prime.";
}
}
protected boolean testPrimeNumber(long number) {
// Count the number of times we test for a prime number
registry.counter("example.prime.number").increment();
for (int i = 3; i < Math.floor(Math.sqrt(number)) + 1; i = i + 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
可能需要尝试向计数器添加标签或标签来指示要检查的值。请记住,指标名称(testPrimeNumber)和标签值的每个唯一组合都会生成唯一的时间序列。将未绑定的数据集用作标签值可能会导致"cardinality explosion",创建新时间序列的指数增加。
但是,可以添加一个标签来传递较少的信息。在以下示例中,进行了调整,计数器被移动以添加一些标签。
@GET
@Path("prime/{number}")
public String checkIfPrime(@PathParam("number") long number) {
if (number < 1) {
registry.counter("example.prime.number", "type", "not-natural").increment();
return "Only natural numbers can be prime numbers.";
}
if (number == 1 ) {
registry.counter("example.prime.number", "type", "one").increment();
return number + " is not prime.";
}
if (number == 2 || number % 2 == 0) {
registry.counter("example.prime.number", "type", "even").increment();
return number + " is not prime.";
}
if ( testPrimeNumber(number) ) {
registry.counter("example.prime.number", "type", "prime").increment();
return number + " is prime.";
} else {
registry.counter("example.prime.number", "type", "not-prime").increment();
return number + " is not prime.";
}
}
protected boolean testPrimeNumber(long number) {
for (int i = 3; i < Math.floor(Math.sqrt(number)) + 1; i = i + 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
查看此计数器生成的数据,您可以告诉如何检查负数或数字数,或者一个数字数,等等。尝试以下序列,并在纯文本输出中查找 example_prime_number_total。请注意,当 Micrometer 将 Prometheus 命名约定应用到 example.prime.number (最初指定的计数器名称)时,会添加 _total 后缀。
# If you did not leave quarkus running in dev mode, start it again:
./mvnw compile quarkus:dev
curl http://localhost:8080/example/prime/-1
curl http://localhost:8080/example/prime/0
curl http://localhost:8080/example/prime/1
curl http://localhost:8080/example/prime/2
curl http://localhost:8080/example/prime/3
curl http://localhost:8080/example/prime/15
curl http://localhost:8080/q/metrics
永不可以计算您可以花费时间或总结的时间。计数器仅记录一个计数,这可能是需要的。但是,如果您想要了解更多有关值变化的信息,计时器(当测量的基本单位为时间时),或者分布概述可能更为合适。
总结和时间
Micrometer 中的计时器和发行版摘要非常相似。两者都允许您记录观察到的值,该值将与其他记录的值合并,并作为总和保存。Micrometer 还递增计数器,以指示已记录的测量数量,并在指定时间段内跟踪最大观察到的值。
分发摘要通过调用 记录 方法记录观察到的值来填充,而计时器则提供特定于时间和测量持续时间的额外功能。例如,我们可以使用计时器来测量使用打包机制调用 的记录 方法之一计算主数字所需的时间:
protected boolean testPrimeNumber(long number) {
Timer timer = registry.timer("example.prime.number.test");
return timer.record(() -> {
for (int i = 3; i < Math.floor(Math.sqrt(number)) + 1; i = i + 2) {
if (number % i == 0) {
return false;
}
}
return true;
});
}
Micrometer 在为这个计时器发出指标时会应用 Prometheus 约定。Prometheus 测量时间(以秒为单位)。Micrometer 将测量的持续时间转换为秒,并按惯例在指标名称中包含单元。在访问 prime 端点后,查看以下三个条目的纯文本输出: example_prime_number_test_seconds_count,example_prime_number_test_seconds_sum, 和 example_prime_number_test_seconds_max。
# If you did not leave quarkus running in dev mode, start it again:
./mvnw compile quarkus:dev
curl http://localhost:8080/example/prime/256
curl http://localhost:8080/q/metrics
curl http://localhost:8080/example/prime/7919
curl http://localhost:8080/q/metrics
计时器和发行版摘要都可以配置为发出其他统计信息,如直方图数据、预计算百分比或服务级别目标(SLO)边界。请注意,计数、总和直方数据可以在维度(或一系列实例内)中重新聚合,而预先计算的值则不能被重新计算。
第 4 章 HTTP 指标 复制链接链接已复制到粘贴板!
Micrometer 扩展会自动扩展 HTTP 服务器请求的时间。按照计时器的 Prometheus 命名惯例,查找 http_server_requests_seconds_count、http_server_requests_seconds_sum 和 http_server_requests_seconds_max。为请求的 uri、HTTP 方法(GET、POST 等)、状态代码(200、302、404 等)和更常规的结果字段添加了维度标签。
# HELP http_server_requests_seconds
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/prime/{number}",} 6.0
http_server_requests_seconds_sum{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/prime/{number}",} 0.007355093
http_server_requests_seconds_count{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/gauge/{number}",} 4.0
http_server_requests_seconds_sum{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/gauge/{number}",} 0.005035393
# HELP http_server_requests_seconds_max
# TYPE http_server_requests_seconds_max gauge
http_server_requests_seconds_max{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/prime/{number}",} 0.002110405
http_server_requests_seconds_max{env="test",method="GET",outcome="SUCCESS",registry="prometheus",status="200",uri="/example/gauge/{number}",} 0.00239441
忽略端点
您可以使用 quarkus.micrometer.binder.http-server.ignore-patterns 属性禁用 HTTP 端点的测量。此属性接受以逗号分隔的简单正则表达式匹配模式列表,该模式标识应忽略的 URI 路径。例如,设置 quarkus.micrometer.binder.http-server.ignore-patterns=/example/prime/[0-9]+ 将忽略对 http://localhost:8080/example/prime/7919 的请求。对 http://localhost:8080/example/gauge/7919 的请求仍会被测量。
URI 模板
Micrometer 扩展将在 代表以模板形式包含路径参数的 URI 时进行最佳工作。使用以上示例,对 http://localhost:8080/example/prime/7919 的请求应该显示为 http_server_requests_seconds 指标数据的属性,标签为 uri=/example/prime/{number}。
如果无法确定正确的 URL,请使用 quarkus.micrometer.binder.http-server.match-patterns 属性。此属性接受以逗号分隔的列表,定义简单正则表达式匹配模式和替换字符串之间的关联。例如,每当请求的 uri 匹配 /prime/[0-9]+ 将值 /example/prime/[0-9]+ 时,设置 quarkus.micrometer.binder.http-server.match-patterns=/example/example/{jellybeans} 用于 uri 属性。
第 5 章 可靠性指标 复制链接链接已复制到粘贴板!
可靠性指标用于使用限定措施表达软件组件的可靠性。您使用的指标取决于应用可靠性指标的系统类型以及应用域的要求。从站点可靠性工程角度来说,需要专注于 Java 应用程序的一些关键指标。
失败的时间
平均故障时间(MTTF)是两个连续故障之间的时间间隔。您用于测量 MTTF 的时间单元取决于系统,还可由事务数量定义。对于具有大型事务的系统,MTTF 通常一致。
修复的时间
补救时间(MTTR)是跟踪导致失败和修复错误所花费的平均时间。
表示故障之间的时间
当您组合 MTTF 和 MTTR 指标时,结果等于 Mean Time Failure (MTBF)。时间测量是实时的,而不是 MTTF 中包含的执行时间。
失败的速度
失败率(ROCOF)是以单元时间间隔内发生的故障次数,并专注于经常发生、意外事件的可能性。
Demand 上的故障的可能性
在 Demand (POFOD)失败的可能性是系统在发出服务请求时失败的概率。POFOD 是安全关键系统以及偶尔需要服务的安全系统保护系统的重要措施。
Availabiity
可用性测量系统可在任意给定时间使用的可能性。您必须考虑修复时间和系统的重启时间。
第 6 章 与 OpenShift 集成 复制链接链接已复制到粘贴板!
您可以使 Quarkus 应用程序能够将 Micrometer 指标库用于运行时和应用程序指标。Micrometer 在应用程序和第三方(如 Prometheus)之间表现上相似,它们嵌入在 OpenShift 中。Quarkus 与 OpenShift 的集成不仅可以公开自动启用的嵌入式指标,还可以公开作为应用程序注册的自定义指标。
有关配置各种指标的更多信息,请参阅 Quarkus Micrometer 社区指南。
先决条件
- 您可以访问 OpenShift CLI、4.6 或更高版本
- 您有一个 OpenShift 实例
流程
完成以下说明并在 OpenShift 中使用嵌入式 Prometheus 来公开 Quarkus 应用程序的指标:
6.1. 在 OpenShift 中为用户定义的项目启用监控 复制链接链接已复制到粘贴板!
在 Red Hat OpenShift Container Platform 4.6 或更高版本中,您可以为用户定义的项目以及默认平台监控启用监控。
先决条件
- 有权访问 OpenShift CLI、4.6 或更高版本
- 有一个 OpenShift 实例
流程
-
前往 为用户定义的项目启用监控,并按照如何启用用户定义的项目监控的具体说明进行操作。在概述中,您将在命名空间
openshift-monitoring中创建 ConfigMap
cluster-monitoring-config.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-monitoring-config
namespace: openshift-monitoring
data:
config.yaml: |
enableUserWorkload: true
如果使用 OpenShift 4.5 或更早版本,请使用:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-monitoring-config
namespace: openshift-monitoring
data:
config.yaml: |
techPreviewUserWorkload:
enabled: true
完成为用户定义的项目启用监控的步骤后,OpenShift 会自动创建一个命名空间 openshift-user-workload-monitoring,在开始将 Quarkus 应用程序部署到 OpenShift 并在 OpenShift 中创建服务监控器时,将 进行部署。
6.2. 将 Quarkus 应用程序部署到 OpenShift 复制链接链接已复制到粘贴板!
设置所需的基础架构后,您必须使用 Prometheus 启用 Micrometer。
先决条件
- 您可以访问 OpenShift CLI、4.6 或更高版本
- 您有一个 OpenShift 实例
- 您已在上一节中创建了一个 ConfigMap,在 OpenShift 中为用户定义的项目启用监控
流程
实现 REST API:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency>添加 micrometer registry facade:
import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import io.micrometer.core.instrument.MeterRegistry; @Path("/hello") public class GreetingsResource { @Inject MeterRegistry registry; @GET public String sayHello() { registry.counter("greeting_counter").increment(); return "Hello!"; } }这个 Micrometer facade 创建一个计数器,每次调用服务时都会递增。registry 帮助创建自定义指标或手动使用指标。您还可以按如下方式注解方法:
@GET @Counted(value = "greeting_counter") public String sayHello() { return "Hello!"; }运行应用程序:
mvn compile quarkus:dev调用您的服务:
curl http://localhost:8080/hello该服务应该返回
Hello!浏览到
http://localhost:8080/q/metrics。您应该会看到带有计数 1.0 的greeting_counter(您刚刚完成的一个):# HELP greeting_counter_total #TYPE greeting_counter_total counter greeting_counter_total 1.0通过在
pom.xml中输入扩展quarkus-openshift,将 Quarkus 应用程序部署到 OpenShift 中:<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-openshift</artifactId> </dependency>在 OpenShift 中将应用程序部署到名为
my-project的新创建的项目中:oc new-project my-project mvn clean package -Dquarkus.kubernetes.deploy=true -Dquarkus.openshift.expose=true -Dquarkus.openshift.labels.app-with-metrics=quarkus-app
app-with-metrics 在 OpenShift 项目中创建服务监控器。
如果您使用没有安全 SSL 的 OpenShift,您还需要将 -Dquarkus.kubernetes-client.trust-certs=true 附加到 Maven 命令。
6.3. 在 OpenShift 项目中创建服务监控器 复制链接链接已复制到粘贴板!
Prometheus 使用拉取模型从应用程序获取指标,这意味着它会提取或监视端点来拉取指标。虽然前面的步骤开始在 OpenShift 实例中公开服务,但还没有在 Prometheus 中配置任何内容来提取您的服务。这就是需要服务监控器的原因。
服务监控器是一个自定义资源,您必须在运行服务的同一项目中创建它: my-project。
流程
设置
service-monitor.yaml:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: k8s-app: prometheus-app-monitor name: prometheus-app-monitor namespace: my-project spec: endpoints: - interval: 30s targetPort: 8080 scheme: http selector: matchLabels: app-with-metrics: 'quarkus-app'应用您的 service-monitor.yaml :
oc apply -f service-monitor.yaml此命令创建一个名为
prometheus-app-monitor的服务监控器,它将选择带有标签app-with-metrics: quarkus-app的应用程序。此标签 在将 Quarkus 应用程序部署到 OpenShift 过程中添加。OpenShift 为标记为app-with-metrics: quarkus-app的所有服务调用端点/metrics。使用您的服务监控器:
-
调用您的问候服务:
curl http://quarkus-micrometer-my-project.ocp.host/hello。这会递增您的greeting_counter_total计数器。 - 要查看指标,请浏览 OpenShift 控制台并选择 Developer > Monitoring 视图。
- 选择 Metrics 选项卡。
-
在 Custom Query 字段中,输入
greeting_counter_total。
-
调用您的问候服务:
指标显示在 Custom Query 字段的下表中。