文档菜单
文档首页
/ / /
Java反应式流驱动程序

监控您的部署

本页内容

  • 概述
  • 监控事件
  • 命令事件
  • 服务器发现和监控事件
  • 连接池事件
  • 使用 JMX 监控连接池事件
  • JMX 支持
  • JMX 和 JConsole 示例
  • 将驱动程序包含在您的分布式跟踪系统中
  • API 文档

在本指南中,您可以了解如何在 Java 反应式流驱动程序中设置和配置 监控

监控是收集有关运行程序执行活动的信息的过程,用于在应用程序或应用程序性能管理库中使用。

监控 MongoDB Java 驱动程序可以帮助您了解驱动程序的资源使用和性能,并有助于您在设计和应用调试时做出明智的决定。

在本指南中,您将学习如何执行以下任务

  • 使用MongoDB Java驱动程序监控不同类型的事件

  • 使用Java管理扩展(JMX)和JConsole监控连接池事件

要监控一个事件,您必须在您的MongoClient实例上注册一个监听器

事件是运行中的程序发生的任何动作。驱动程序包括在驱动程序运行时监听发生的事件子集的功能。

监听器是在某些事件发生时执行某些操作的类。监听器的API定义了它可以响应的事件。

监听器类的每个方法代表对某个事件的响应。每个方法接收一个参数:一个代表该方法响应的事件的对象。

MongoDB Java驱动程序将其定义的事件组织成三个类别

  • 命令事件

  • 服务器发现和监控事件

  • 连接池事件

以下各节将展示如何监控每个事件类别。

有关您可以监控的所有事件的完整列表,请查看MongoDB Java驱动程序的事件包。

命令事件是与MongoDB数据库命令相关的事件。一些会产生命令事件的数据库命令示例包括:findinsertdeletecount

要监控命令事件,创建一个实现CommandListener接口的类,并将该类的实例注册到您的MongoClient实例中。

有关MongoDB数据库命令的更多信息,请参阅MongoDB服务器手册中的数据库命令

注意

内部命令

驱动程序不会为其内部调用的命令发布事件。这包括驱动程序用来监控您的集群的数据库命令以及与连接建立相关的命令(例如初始的hello命令)。

重要

被编辑的输出

作为安全措施,驱动程序编辑了一些命令事件的内容。这保护了这些命令事件中包含的敏感信息。有关被编辑命令事件的完整列表,请参阅MongoDB命令日志和监控规范

以下示例展示了如何为数据库命令创建计数器。该计数器记录驱动程序成功执行每个数据库命令的次数,并在每次数据库命令完成后打印此信息。

要实现计数器,请执行以下步骤

  1. 创建一个具有计数功能的类,实现CommandListener接口。

  2. 将实现CommandListener的新类实例添加到MongoClientSettings对象中。

  3. 使用MongoClientSettings对象配置MongoClient实例。

以下代码定义了实现CommandListener接口的CommandCounter类。

class CommandCounter implements CommandListener {
private final Map<String, Integer> commands = new HashMap<String, Integer>();
@Override
public synchronized void commandSucceeded(final CommandSucceededEvent event) {
String commandName = event.getCommandName();
int count = commands.getOrDefault(commandName, 0);
commands.put(commandName, count + 1);
System.out.println(commands);
}
@Override
public void commandFailed(final CommandFailedEvent event) {
System.out.printf("Failed execution of command '%s' with id %s%n",
event.getCommandName(),
event.getRequestId());
}
}

以下代码将CommandCounter类的实例添加到MongoClientSettings对象中,并使用该对象配置MongoClient实例。然后代码运行一些数据库命令以测试计数器。

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.addCommandListener(new CommandCounter())
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run some commands to test the counter
FindPublisher<Document> findPublisher1 = collection.find();
FindPublisher<Document> findPublisher2 = collection.find();
Flux.from(findPublisher1).blockLast();
Flux.from(findPublisher2).blockLast();
}
{find=1}
{find=2}
{find=2, endSessions=1}

服务器发现和监控(SDAM)事件是与您连接的MongoDB实例或集群状态变化相关的事件。

驱动程序定义了九个SDAM事件。驱动程序将这些九个事件分为三个独立的监听器接口,每个接口监听九个事件中的三个。以下是三个接口以及它们监听的事件:

  • ClusterListener拓扑相关事件

  • ServerListener:与mongodmongos进程相关的事件

  • ServerMonitorListener:心跳相关的事件

要监控某种SDAM事件,编写一个实现上述三个接口之一的类,并将该类的实例注册到您的MongoClient实例中。

有关驱动程序中每个SDAM事件的详细描述,请参阅MongoDB SDAM 日志和监控规范。

注意

负载均衡模式

在负载均衡模式下,驱动程序不会发出与心跳相关的事件。有关带有负载均衡的SDAM事件的更多详细信息,请参阅MongoDB 负载均衡器支持规范。

以下示例演示了如何创建一个监听器类,该类可以打印一条消息,告知您驱动程序是否可以写入您的MongoDB实例。

以下代码定义了一个实现ClusterListener接口的IsWritable类。

class IsWritable implements ClusterListener {
private boolean isWritable;
@Override
public synchronized void clusterDescriptionChanged(final ClusterDescriptionChangedEvent event) {
if (!isWritable) {
if (event.getNewDescription().hasWritableServer()) {
isWritable = true;
System.out.println("Able to write to server");
}
} else if (!event.getNewDescription().hasWritableServer()) {
isWritable = false;
System.out.println("Unable to write to server");
}
}
}

以下代码将IsWritable类的一个实例添加到MongoClient对象中。然后代码运行一个查找操作来测试IsWritable类。

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToClusterSettings(builder ->
builder.addClusterListener(new IsWritable()))
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger a ClusterDescriptionChangedEvent
FindPublisher<Document> findPublisher = collection.find();
Flux.from(findPublisher).blockLast();
}
Able to write to server

连接池事件是与驱动程序持有的连接池相关的事件。连接池是驱动程序与MongoDB部署维护的一组打开的TCP连接。连接池有助于减少您的应用程序与MongoDB部署之间需要执行的网络握手次数,并可以帮助您的应用程序运行更快。

要监控连接池事件,编写一个实现ConnectionPoolListener接口的类,并将该类的实例注册到您的MongoClient实例。

以下示例展示了如何创建一个监听器类,每次从您的连接池检查连接时都打印一条消息。

以下代码定义了实现ConnectionPoolListener接口的ConnectionPoolLibrarian类。

class ConnectionPoolLibrarian implements ConnectionPoolListener {
@Override
public void connectionCheckedOut(final ConnectionCheckedOutEvent event) {
System.out.printf("Fetching the connection with id %s...%n",
event.getConnectionId().getLocalValue());
}
@Override
public void connectionCheckOutFailed(final ConnectionCheckOutFailedEvent event) {
System.out.println("Something went wrong! Failed to checkout connection.");
}
}

以下代码将ConnectionPoolLibrarian类的实例添加到MongoClient对象中。然后代码执行数据库命令以测试图书管理员。

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToClusterSettings(builder ->
builder.addClusterListener(new IsWritable()))
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger a ClusterDescriptionChangedEvent
FindPublisher<Document> findPublisher = collection.find();
Flux.from(findPublisher).blockLast();
}
Let me get you the connection with id 21...

您可以使用 Java管理扩展(JMX) 来监控连接池事件。JMX提供了监控应用程序和设备的工具。

有关JMX的更多信息,请参阅Oracle JMX官方文档。

要启用JMX连接池监控,请将 JMXConnectionPoolListener 类的实例添加到您的 MongoClient 对象。

JMXConnectionPoolListener 类执行以下操作

  1. 为每个与驱动程序维护连接池的 mongodmongos 进程创建MXBean实例

  2. 将这些MXBean实例注册到平台MBean服务器

注册在平台MBean服务器上的MXBean具有以下属性

属性
描述
clusterId
客户端生成的唯一标识符。该标识符确保当应用程序有多个连接到同一MongoDB部署的 MongoClient 实例时,驱动程序创建的每个MXBean都有一个唯一名称。
host
运行 mongodmongos 进程的机器的主机名。
port
mongodmongos 进程正在监听的端口号。
minSize
连接池的最小大小,包括空闲和正在使用的连接。
maxSize
连接池的最大大小,包括空闲和正在使用的连接。
size
当前连接池的大小,包括空闲和正在使用的连接。
checkedOutCount
当前正在使用的连接数。

驱动程序创建的所有MXBean实例都在域"org.mongodb.driver"下。

有关本节讨论主题的更多信息,请参阅以下Oracle资源

以下示例显示了如何使用JMX和JConsole监控驱动程序的连接池。JConsole是Java平台附带的JMX兼容的GUI监控工具。

提示

查阅官方JMX和JConsole文档

本例中JMX和JConsole的描述仅供参考,而非真实信息来源。为确保信息准确,请查阅以下官方Oracle资源

以下代码片段向MongoClient实例添加了一个JMXConnectionPoolListener。然后代码暂停执行,以便您可以导航到JConsole并检查您的连接池。

JMXConnectionPoolListener connectionPoolListener = new JMXConnectionPoolListener();
try (MongoClient mongoClient = MongoClients.create(URI)) {
System.out.println("Navigate to JConsole to see your connection pools...");
// Pauses the code execution so you can navigate to JConsole and inspect your connection pools
Thread.sleep(Long.MAX_VALUE);
}
Navigate to JConsole to see your connection pools...

启动您的服务器后,在终端中运行以下命令打开JConsole

jconsole

JConsole打开后,在GUI中执行以下操作

  1. 选择运行上述示例代码的Java进程。

  2. 点击不安全连接在警告对话框中。

  3. 点击MBeans标签页。

  4. "org.mongodb.driver"域下检查您的连接池事件。

当您不再需要使用JConsole检查连接池时,请执行以下任务

  1. 关闭JConsole窗口退出JConsole。

  2. 停止运行上述代码片段的Java程序。

有关JMX和JConsole的更多信息,请参阅以下Oracle资源

有关 JMXConnectionPoolListener 类的更多信息,请参阅 JMXConnectionPoolListener.

如果您使用的是 分布式跟踪系统,则可以将驱动程序的事件数据包含在内。分布式跟踪系统是一种应用,它跟踪请求如何在面向服务的架构中传播到不同的服务中。

如果您在Spring Cloud应用程序中使用驱动程序,请使用Spring Cloud Sleuth将MongoDB事件数据包含到Zipkin分布式跟踪系统中。

如果您不使用Spring Cloud或必须在除了Zipkin之外的分布式追踪系统中包含驱动事件数据,您必须编写一个命令事件监听器来管理您所需的分布式追踪系统中的跨度。要查看此类监听器的实现,请参阅Spring Cloud Sleuth源代码中的TraceMongoCommandListener类。

要了解有关Spring Cloud Sleuth的更多信息,请参阅Spring Cloud Sleuth文档中的入门指南,链接为入门指南

要查看分布式跟踪系统的详细描述,请参阅Google Research上的Dapper,链接为Dapper

有关本文档中提到的类和方法的更多信息,请参阅以下API文档

返回

日志记录