Docs 菜单
Docs 主页
/ / /
Java Reactive Streams 驱动程序

监控部署

在此页面上

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

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

监控是收集正在运行的程序所执行的活动信息以用于应用程序或应用程序性能管理库的过程。

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

在本指南中,您将了解如何执行以下任务:

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

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

如需监控事件,必须在 MongoClient 实例上注册监听器

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

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

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

MongoDB Java 驱动程序将其定义的事件分为三类:

  • 命令事件

  • 服务器发现和监控事件

  • 连接池事件

以下部分将介绍如何监控每个事件类别。

有关可以监控的事件的完整列表, 请参阅 MongoDB Java 驱动程序的事件包。

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

要监控命令事件,请创建一个实现CommandListener接口的类,并使用MongoClient实例注册该类的实例。

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

注意

内部命令

此驱动程序不会为其内部调用的命令发布事件。其中包括该驱动程序用于监控群集的数据库命令,以及与连接建立相关的命令(例如初始 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 对象中,并使用 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();
}

服务器发现与监控 (SDAM) 事件是指与驱动程序连接到的 MongoDB 实例或集群的状态变化相关的事件。

驱动程序定义了 9 个 SDAM 事件。驱动程序将这 9 个事件分给 3 个独立的监听器接口,每个接口监听 9 个事件中的 3 个。以下是 3 个接口及其监听的事件:

  • ClusterListener 拓扑结构 相关事件

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

  • ServerMonitorListener:心跳相关事件

如需监控 SDAM 事件类型,请编写实现上述 3 个接口之一的类,然后将该类的实例注册到您的 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();
}

连接池事件是与驱动程序持有的连接池相关的事件。连接池是驱动程序通过 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();
}

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

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

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

JMXConnectionPoolListener 类执行以下操作:

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

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

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

属性
说明
clusterId
客户端生成的唯一标识符。当应用程序有多个 MongoClient 实例连接到同一 MongoDB 部署时,该标识符可确保驱动程序生成的每个 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 官方资源:

以下代码段将 JMXConnectionPoolListener 添加到 MongoClient 实例。然后代码暂停执行,以便您可以导航到 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);
}

启动服务器后,通过在终端中运行以下命令来打开 JConsole:

jconsole

打开 JConsole 后,在图形界面中执行以下操作:

  1. 选择运行前面示例代码的 Java 进程。

  2. 单击警告对话框中的 Insecure Connection

  3. 单击 MBeans 标签页。

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

当您不想再在 JConsole 中检查连接池时,请执行以下任务:

  1. 关闭 JConsole 窗口以退出 JConsole。

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

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

有关JMXConnectionPoolListener 类的更多信息,请参阅 JMXConnectionPoolListener 的 API 文档。

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

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

如果您不使用 Spring Cloud 或必须在 Zipkin 以外的分布式跟踪系统中包含驱动程序事件数据,则必须编写一个命令事件监听器来管理 span 所需的分布式跟踪系统。要查看此类侦听器的实现,请 参阅 类。

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

要查看分布式跟踪系统的详细说明,请参阅 Google Research 发布的 Dapper

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

后退

日志记录