跳至主要内容

RabbitMQ Java 客户端指标与 Micrometer 和 Datadog

·阅读时长 6 分钟

在这篇文章中,我们将介绍 RabbitMQ Java 客户端库如何收集运行时指标并将其发送到 JMX 和 Datadog 等监控系统。

RabbitMQ Java 客户端中的 Micrometer

从 4.6.0 和 5.2.0 版本开始,Java 客户端提供对 Micrometer 的支持。这带来了什么好处?Micrometer 是一个指标门面:应用程序可以使用 Micrometer API 收集指标,并选择将这些指标发送到不同的后端,例如 JMX、Prometheus、Netflix Atlas、CloudWatch、Datadog、Graphite、Ganglia 等。接下来,我们将了解 RabbitMQ Java 客户端用户如何从 Micrometer 的优势中获益。

我们可以从收集 Java 客户端指标并使用 Micrometer 将其暴露在 JMX 上开始。

MeterRegistry jmxRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM);
ConnectionFactory connectionFactory = new ConnectionFactory();
MicrometerMetricsCollector metricsCollector = new MicrometerMetricsCollector(
jmxRegistry, "rabbitmq.client"
);
connectionFactory.setMetricsCollector(metricsCollector);

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String queue = channel.queueDeclare().getQueue();
channel.basicConsume(queue, true, (ctag, msg) -> { }, (ctag) -> { });
executor.submit(() -> {
Random random = new Random();
while (true) {
Thread.sleep(random.nextInt(100));
channel.basicPublish("", queue, null, "".getBytes());
}
});

然后,可以在 VisualVM 中检查这些指标。

Java Client Metrics on JMX
JMX 上的 Java 客户端指标

与我们在 之前的帖子 中使用 Dropwizard Metrics 所做的事情相比,并没有什么新意。

但 Micrometer 可以轻松地通过与 JVM 进程相关的指标带来价值。我们只需要将相应的 MeterBinder 绑定到 JMX 指标注册表。

MeterRegistry jmxRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM);
// JVM and system metrics:
new ClassLoaderMetrics().bindTo(jmxRegistry);
new JvmMemoryMetrics().bindTo(jmxRegistry);
new JvmGcMetrics().bindTo(jmxRegistry);
new ProcessorMetrics().bindTo(jmxRegistry);
new JvmThreadMetrics().bindTo(jmxRegistry);
ConnectionFactory connectionFactory = new ConnectionFactory();
MicrometerMetricsCollector metricsCollector = new MicrometerMetricsCollector(
jmxRegistry, "rabbitmq.client"
);
connectionFactory.setMetricsCollector(metricsCollector);

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String queue = channel.queueDeclare().getQueue();
channel.basicConsume(queue, true, (ctag, msg) -> { }, (ctag) -> { });
executor.submit(() -> {
Random random = new Random();
while (true) {
Thread.sleep(random.nextInt(100));
channel.basicPublish("", queue, null, "".getBytes());
}
});

然后,新的指标就会出现在 JVisualVM 中,数量相当多。

Java Client,JVM, and System Metrics on JMX
JMX 上的 Java 客户端、JVM 和系统指标

在实践中,应用程序通常会同时运行多个实例,有时还会分布在不同的数据中心。我们如何识别在给定数据中心运行的实例,并使监控系统了解此信息?Micrometer 提供了指标标签:只需要将数据中心信息添加到指标收集器即可。我们可以调整我们的示例程序,并遍历数据中心列表来模拟分布式实例。我们使用 dc 标签表示数据中心信息,并添加 host 标签。

for (String dc : new String[] {"us", "europe", "asia"}) {
Tags tags = Tags.of("host", hostname, "dc", dc);
MeterRegistry jmxRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM);
new ClassLoaderMetrics(tags).bindTo(jmxRegistry);
new JvmMemoryMetrics(tags).bindTo(jmxRegistry);
new JvmGcMetrics(tags).bindTo(jmxRegistry);
new ProcessorMetrics(tags).bindTo(jmxRegistry);
new JvmThreadMetrics(tags).bindTo(jmxRegistry);
ConnectionFactory connectionFactory = new ConnectionFactory();
MicrometerMetricsCollector metricsCollector = new MicrometerMetricsCollector(
jmxRegistry, "rabbitmq.client", tags
);
connectionFactory.setMetricsCollector(metricsCollector);

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String queue = channel.queueDeclare().getQueue();
channel.basicConsume(queue, true, (ctag, msg) -> { }, (ctag) -> { });
executor.submit(() -> {
Random random = new Random();
int offset = dc.length() * 10;
while (true) {
Thread.sleep(random.nextInt(100) + offset);
channel.basicPublish("", queue, null, "".getBytes());
}
});
}

让我们看看它在 VisualVM 中的样子。

Java Client Metrics for Different Datacenters on JMX
JMX 上不同数据中心的 Java 客户端指标

现在,指标列表变得很长,因为 Micrometer 会展平标签/键值对集并将它们添加到名称中。这是因为 JMX 是一个分层监控系统,不支持维度。这使得难以对所有实例和数据中心的指标进行整体分析。在现实生活中,情况会更糟:这里我们在同一个 JVM 进程中模拟了应用程序的不同实例,但在真正的系统中,每个进程都会有一个标签,分析起来更加困难。

幸运的是,Micrometer 利用了维度监控系统。想象一下,我们可以看到不同实例的聚合指标,并深入到特定的数据中心或主机。

Datadog 就是这样一个系统,Micrometer 原生支持它。我们可以使用 DatadogMeterRegistry 并继续使用 JMX,这得益于 CompositeMeterRegistry

for (String dc : new String[] {"us", "europe", "asia"}) {
CompositeMeterRegistry compositeMeterRegistry = new CompositeMeterRegistry();
MeterRegistry datadogRegistry = new DatadogMeterRegistry(config, Clock.SYSTEM);
MeterRegistry jmxRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM);

Tags tags = Tags.of("host", hostname, "dc", dc);
new ClassLoaderMetrics(tags).bindTo(compositeMeterRegistry);
new JvmMemoryMetrics(tags).bindTo(compositeMeterRegistry);
new JvmGcMetrics(tags).bindTo(compositeMeterRegistry);
new ProcessorMetrics(tags).bindTo(compositeMeterRegistry);
new JvmThreadMetrics(tags).bindTo(compositeMeterRegistry);

compositeMeterRegistry.add(datadogRegistry);
compositeMeterRegistry.add(jmxRegistry);

ConnectionFactory connectionFactory = new ConnectionFactory();
MicrometerMetricsCollector metricsCollector = new MicrometerMetricsCollector(
compositeMeterRegistry, "rabbitmq.client", tags
);
connectionFactory.setMetricsCollector(metricsCollector);

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String queue = channel.queueDeclare().getQueue();
channel.basicConsume(queue, true, (ctag, msg) -> { }, (ctag) -> { });
executor.submit(() -> {
Random random = new Random();
int offset = dc.length() * 10;
while (true) {
Thread.sleep(random.nextInt(100) + offset);
channel.basicPublish("", queue, null, "".getBytes());
}
});
}

幕后发生了什么?Micrometer 会收集指标,并每 10 秒通过 HTTPS 将其发送到 Datadog 服务。请注意,要使此功能正常工作,需要一个 Datadog API 密钥,该密钥用于 Datadog 注册表配置。主机和指标应该会显示在 Datadog Web UI 中,您可以轻松地为 RabbitMQ Java 客户端实例构建仪表板。

RabbitMQ Java Client Metrics Datadog Dashboard
RabbitMQ Java 客户端指标 Datadog 仪表板

是不是很酷?

更进一步

在单个级别收集指标(例如,特定的库,如 RabbitMQ Java 客户端)只是在获得对整个面向服务的系统可见性的道路上的第一步。

Datadog 还提供了对 RabbitMQ 节点和集群 的支持。节点需要安装 Datadog 代理,该代理将连接到 RabbitMQ 管理插件 来收集指标。Datadog 工程师撰写了一系列 文章,其中介绍了 如何监控 RabbitMQ。对于任何对 RabbitMQ 操作感兴趣的人来说,这些文章都是值得推荐的阅读材料。

回到客户端级别,Spring Boot 是用 Java 编写 RabbitMQ 应用程序的流行方法。Micrometer 是支持 Spring Boot 2.0 指标系统的库。RabbitMQ Java 客户端指标收集是 自动配置的,开发人员甚至不需要注册任何 MetricsCollector

在微服务和物联网工作负载的世界中,应用程序实例像蘑菇一样涌现,我们希望这能够让您更轻松地通过这些指标了解使用 RabbitMQ 进行消息传递的基于 Java 的应用程序的操作可见性!

源代码

© 2024 RabbitMQ. All rights reserved.