跳至主内容

使用 Micrometer 和 Datadog 的 RabbitMQ Java 客户端指标

·6 分钟阅读

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

Micrometer 在 RabbitMQ Java 客户端中的应用

从 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,并通过 CompositeMeterRegistry 继续使用 JMX

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 收集指标,并通过 HTTPS 每 10 秒发送到 Datadog 服务。请注意,这需要 Datadog API 密钥才能正常工作,它在 Datadog 注册表配置中使用。主机和指标应该会显示在您的 Datadog Web UI 中,您可以轻松地为您的 RabbitMQ Java 客户端实例构建仪表板

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

是不是很方便?

深入探索

在一个层面收集指标——例如,像 RabbitMQ Java 客户端这样的特定库——仅仅是深入了解整个面向服务的系统可见性的一小步。

Datadog 还提供了对 RabbitMQ 节点和集群的支持。节点需要安装 Datadog 代理,该代理将连接到 RabbitMQ 管理插件 来收集指标。Datadog 工程师撰写了一系列 博文,涵盖了 如何监控 RabbitMQ。对于任何对 RabbitMQ 运维感兴趣的人来说,这是推荐阅读的内容。

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

在微服务和 IoT 工作负载的世界中,应用程序实例如雨后春笋般涌现,我们希望这些指标能够更轻松地提高对使用 RabbitMQ 进行消息传递的 Java 应用程序的可见性!

源代码

© . This site is unofficial and not affiliated with VMware.