深入探索 MicroProfile Metrics:从入门到应用
1. 开启 MicroProfile Metrics 之旅
在开始使用 MicroProfile Metrics 之前,我们需要完成服务的部署。通过以下命令将服务部署到 Kubernetes:
mvn clean package -DskipTests -Dquarkus.kubernetes.deploy=true
cd ../transaction-service
mvn clean package -DskipTests -Dquarkus.kubernetes.deploy=true
部署完成后,查看仪表盘,大约 15 到 30 秒内,“Used Heap” 面板会更新每个服务使用的 JVM 堆信息。需要注意的是,此时只有 JVM Used Heap 面板会更新,其他面板将随着后续对服务进行指标检测而更新。
2. 理解 MicroProfile Metrics
Java 平台自 JDK 5 起就引入了 Java Management Extensions(JMX),但它无法满足现代企业级 Java 应用的指标需求。例如,JMX API 较为复杂,且在 Java 平台引入注解之前就已创建。此外,JMX 既不暴露指标元数据,也不以现代云友好的格式展示指标。为了解决这些问题,MicroProfile 社区创建了 MicroProfile Metrics。
2.1 输出格式
MicroProfile Metrics 要求实现支持两种输出格式:
-
OpenMetrics 格式
:这是由云原生计算基金会(CNCF)定义的标准文本格式,当 HTTP 接受头为
text/plain
时,它是 MicroProfile Metrics 的默认输出格式。示例如下:
# HELP base_classloader_loadedClasses_count Displays the number of classes
that are currently loaded in the Java virtual machine.
# TYPE base_classloader_loadedClasses_count gauge
base_classloader_loadedClasses_count 13010.0
可以使用以下
curl
命令查看特定指标:
curl -i localhost:8080/q/metrics/base/classloader.loadedClasses.count
-
JSON 格式
:通过设置
application/json的 HTTP 请求头,可以获取 JSON 格式的指标输出。示例代码如下:
curl -i \
-H "Accept:application/json" \
localhost:8080/q/metrics
JSON 格式的示例输出:
{
"base": {
"cpu.systemLoadAverage": 2.1865234375,
"thread.count": 60,
"classloader.loadedClasses.count": 9667,
...
},
"vendor": {
...
},
"application": {
...
}
}
需要注意的是,JSON 格式不包含 OpenMetrics 格式中的 TYPE 和 HELP 元数据,它更侧重于高效的机器可读格式。由于 OpenMetrics 是一种标准格式,便于后续被 Prometheus 等工具使用,因此本文重点关注 OpenMetrics 输出。
2.2 命名约定
MicroProfile Metrics 遵循特定的命名约定:
<scope>.<class>.<method>.<name>
。具体说明如下表:
| 约定 | 描述 |
| ---- | ---- |
| Scope | 必须是
base
、
vendor
或
application
,后续会详细解释 |
| Class | 注解应用的包和类名 |
| Method | 注解应用的方法 |
| Name | 指标的名称,如
classloader.loadedClasses.count
|
2.3 指标范围
MicroProfile 将指标分为以下三个范围:
| 范围 | 描述 |
| ---- | ---- |
| Base | 所有 MicroProfile Metrics 实现都需要的指标,例如
base_thread_count
指标可显示运行应用程序进程中的活动线程数,这些指标在不同实现之间具有可移植性 |
| Vendor | 特定于运行时的指标,不具有跨实现的可移植性。例如,Quarkus 特定的
vendor_cpu_processCpuTime_seconds
指标可显示应用程序进程使用的 CPU 时间。随着应用程序使用的扩展数量增加,可用指标的数量也会增加 |
| Application | 由应用程序定义或代表应用程序定义的指标 |
可以通过在指标 URL 后附加范围来直接查询特定范围的指标。例如,请求
base
指标的命令如下:
curl -i localhost:8080/q/metrics/base
2.4 支持的指标类型
MicroProfile Metrics 支持多种常用的指标类型,如下表所示:
| 指标 | 注解 | 描述 |
| ---- | ---- | ---- |
| Counter |
@Counter
| 单调递增的数值 |
| Concurrent gauge |
@ConcurrentGauge
| 递增或递减的值 |
| Gauge |
@Gauge
| 采样以获取当前值的指标 |
| Meter |
@Metered
| 跟踪平均吞吐量以及 1、5 和 15 分钟的指数加权移动平均吞吐量 |
| Metric |
@Metric
| 不是一种指标类型,而是一个注解,用于在请求注入或生成指标时包含元数据信息 |
| Histogram | N/A | 计算值的分布 |
| Timer |
@Timed
| 聚合计时持续时间,提供持续时间统计和吞吐量统计 |
指标注解接受多个参数,具体说明如下表:
| 指标字段 | 描述 |
| ---- | ---- |
| name | 可选,设置指标的名称。如果未明确指定,则使用注解对象的名称 |
| absolute | 如果为
true
,则使用给定的名称作为指标的绝对名称;如果为
false
,则在给定名称前添加包名和类名。默认值为
false
|
| displayName | 可选,用于元数据的人类可读显示名称,方便第三方工具使用 |
| description | 可选,指标的描述,对第三方工具很有用 |
| unit | 指标的单位,如千兆字节、纳秒和百分比等。可以查看
MetricUnits
类获取预定义的单位 |
| tags | 键值对列表,后续会详细介绍 |
3. 为账户服务添加指标
一个有用的起点是统计
ExceptionMapper
被调用的次数。基于这个统计结果,或许可以改进前端 Web UI 或增强 API。可以使用
Counter
指标来统计
ExceptionMapper
的调用次数,示例代码如下:
@Provider
public static class ErrorMapper implements ExceptionMapper<Exception> {
@Metric(
name = "ErrorMapperCounter",
description = "Number of times the AccountResource ErrorMapper is invoked"
)
Counter errorMapperCounter;
@Override
public Response toResponse(Exception exception) {
errorMapperCounter.inc();
...
}
}
通过调用带有无效值的端点可以增加计数器的值。例如,使用以下命令传递无效的账户号码来调用
ErrorMapper
:
curl -i localhost:8080/accounts/234/balance
为了验证计数器是否增加以及计数器元数据是否可用,可以运行以下命令:
curl localhost:8080/q/metrics | grep ErrorMapper
4. 为交易服务添加指标
MicroProfile Metrics 将指标及其元数据存储在
MetricRegistry
中,每个范围(
base
、
vendor
和
application
)都有一个指标注册表。开发者创建的自定义指标存储在
application
范围中。通过唯一的
MetricID
(由指标名称和可选的标签列表组成)可以在
MetricRegistry
中标识一个指标。
4.1 使用标签跟踪回退情况
以
TransactionServiceFallbackHandler.java
为例,它将 Java 异常映射到 HTTP 响应代码。我们可以使用标签来跟踪回退情况,示例代码如下:
public class TransactionServiceFallbackHandler implements
FallbackHandler<Response> {
@Inject
@RegistryType(type = MetricRegistry.Type.APPLICATION)
MetricRegistry metricRegistry;
@Override
public Response handle(ExecutionContext context) {
Logger LOG =
Logger.getLogger(TransactionServiceFallbackHandler.class);
Response response;
String name;
if (context.getFailure().getCause() == null) {
name = context.getFailure().getClass().getSimpleName();
} else {
name = context.getFailure().getCause().getClass().getSimpleName();
}
switch (name) {
case "BulkheadException":
response = Response.status(Response.Status.TOO_MANY_REQUESTS)
.build();
break;
case "TimeoutException":
response = Response.status(Response.Status.GATEWAY_TIMEOUT)
.build();
break;
case "CircuitBreakerOpenException":
case "ConnectTimeoutException":
case "SocketException":
response = Response.status(Response.Status.SERVICE_UNAVAILABLE)
.build();
break;
case "ResteasyWebApplicationException":
case "WebApplicationException":
case "HttpHostConnectException":
response = Response.status(Response.Status.BAD_GATEWAY)
.build();
break;
default:
response =
Response.status(Response.Status.NOT_IMPLEMENTED).build();
}
metricRegistry.counter("fallback",
new Tag("http_status_code",
"" + response.getStatus()))
.inc();
LOG.info("******** " + context.getMethod().getName() + ": " + name + "
********");
return response;
}
}
为了测试回退计数器,可以运行以下命令:
metrics/scripts/overload_bulkhead.sh
脚本执行完成后,运行以下命令查看指标输出:
export TRANSACTION_URL=http:/ /localhost:8088
curl -i -s $TRANSACTION_URL/q/metrics/application | grep -i fallback_total
4.2 使用
@Timed
注解跟踪性能
为了跟踪回退处理程序的性能,可以在
TransactionServiceFallbackHandler.handle()
方法上添加
@Timed
注解,示例代码如下:
public class TransactionServiceFallbackHandler
implements FallbackHandler<Response> {
@Inject
@RegistryType(type = MetricRegistry.Type.APPLICATION)
MetricRegistry metricRegistry;
@Timed(
name = "fallbackHandlerTimer",
displayName = "Fallback Handler Timer",
description = "Time spent handling fallbacks",
absolute = true,
unit=MetricUnits.NANOSECONDS
)
@Override
public Response handle(ExecutionContext context) {
...
}
...
重新部署应用程序后,再次运行
metrics/scripts/force_multiple_fallbacks.sh
脚本。仪表盘上的“Transaction Service Fallback Call Rate Rolling One Minute Average” 仪表将显示
application_fallbackHandlerTimer_one_min_rate_per_second
指标的值,即过去一分钟内方法调用的速率。
4.3 使用
@ConcurrentGauge
跟踪并发请求
另一种监控性能的方法是跟踪方法上的并发请求。可以通过添加
@ConcurrentGauge
注解来实现这一点,以满足服务级别协议(SLA)的要求。
通过以上步骤,我们可以全面地为微服务添加指标,从而更好地监控和优化服务的性能。
深入探索 MicroProfile Metrics:从入门到应用
5. 指标监控实战
在前面的部分,我们已经为账户服务和交易服务添加了指标。接下来,我们将通过一些实际操作,深入了解如何利用这些指标进行监控和分析。
5.1 生成故障并查看指标
为了测试回退计数器和相关指标,我们可以运行以下命令生成故障:
metrics/scripts/force_multiple_fallbacks.sh
该脚本会执行一系列操作,包括:
1. 发送一些请求,部分请求会成功执行,部分请求会超过并发请求限制(Bulkhead 限制)。
2. 将账户服务缩容以触发断路器。
3. 在断路器触发前向已关闭的服务发送请求。
4. 再将账户服务扩容到一个实例并等待其启动。
5. 服务启动后生成更多请求。
脚本执行的输出示例如下:
HTTP/1.1 200 OK
Content-Length: 0
HTTP/1.1 429 Too Many Requests
Content-Length: 0
HTTP/1.1 429 Too Many Requests
Content-Length: 0
HTTP/1.1 200 OK
Content-Length: 0
...
******* DISABLING ACCOUNT SERVICE ******
deployment.apps/account-service scaled
HTTP/1.1 200 OK
Content-Length: 0
HTTP/1.1 502 Bad Gateway
Content-Length: 0
HTTP/1.1 503 Service Unavailable
Content-Length: 0
...
"******* RESTARTING ACCOUNT SERVICE ******"
deployment.apps/account-service scaled
Waiting for container to start
Waiting for container to start
HTTP/1.1 200 OK
Content-Length: 0
脚本执行完成后,我们可以通过以下命令查看指标输出:
export TRANSACTION_URL=http://localhost:8088
curl -i -s $TRANSACTION_URL/q/metrics/application | grep -i fallback_total
输出示例如下:
# TYPE application_fallback_total counter
application_fallback_total{http_status_code="429"} 290.0
这表明在测试过程中,HTTP 状态码为 429(TOO_MANY_REQUESTS)的回退次数为 290 次。
5.2 重新部署服务
如果需要重新部署交易服务到 Minikube,可以使用以下命令:
mvn clean package -DskipTests -Dquarkus.kubernetes.deploy=true
需要注意的是,在 Quarkus 2.x 中,如果尝试使用
mvn package -Dquarkus.kubernetes.deploy=true
重新部署已经存在于 Kubernetes 中的应用程序,可能会导致错误。可以通过先使用
kubectl delete -f /target/kubernetes/minikube.yaml
删除应用程序来解决这个问题。
6. 指标可视化
指标可视化可以帮助我们更直观地了解服务的性能和健康状况。Grafana 是一个常用的指标可视化工具,我们可以在 Grafana 中查看和分析我们添加的指标。
6.1 查看 JVM 堆使用情况
部署完成后,打开 Grafana 仪表盘,大约 15 到 30 秒内,“Used Heap” 面板会更新每个服务使用的 JVM 堆信息。该面板的图形主体显示每个服务的使用堆大小,大约在 5 MB 到 45 MB 之间,具体取决于垃圾回收的时间。图形标题显示相关信息,图例显示交易服务和账户服务,每个服务的值是所有运行服务实例的平均值。
6.2 查看回退指标
通过运行
metrics/scripts/force_multiple_fallbacks.sh
脚本生成故障后,Grafana 仪表盘会相应更新。可以查看“Transaction Service Fallback Call Rate Rolling One Minute Average” 仪表,该仪表显示
application_fallbackHandlerTimer_one_min_rate_per_second
指标的值,即过去一分钟内方法调用的速率。
以下是一个简单的 mermaid 流程图,展示了指标监控和可视化的流程:
graph LR
A[部署服务] --> B[添加指标]
B --> C[生成故障]
C --> D[查看指标输出]
D --> E[重新部署服务]
E --> F[指标可视化]
7. 总结与建议
通过本文的介绍,我们了解了 MicroProfile Metrics 的基本概念、输出格式、命名约定、指标范围、支持的指标类型等内容,并通过实际操作演示了如何为账户服务和交易服务添加指标,以及如何进行指标监控和可视化。
为了更好地使用 MicroProfile Metrics,以下是一些建议:
1.
合理选择指标类型
:根据实际需求选择合适的指标类型,如
Counter
用于统计次数,
Timer
用于跟踪性能等。
2.
使用标签
:标签可以为指标添加额外的维度,方便进行更细致的分析和查询。
3.
定期监控和分析
:定期查看指标数据,及时发现潜在的问题并进行优化。
4.
结合可视化工具
:使用 Grafana 等可视化工具,将指标数据以直观的图表形式展示,便于理解和决策。
通过以上方法,可以有效地利用 MicroProfile Metrics 监控和优化微服务的性能,提高系统的稳定性和可靠性。
超级会员免费看

被折叠的 条评论
为什么被折叠?



