文档菜单
文档首页
/ / /
Java 同步驱动程序
/

监控

在本页面上

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

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

监控是获取有关运行程序执行活动信息的过程,用于应用程序或应用程序性能管理库。

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

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

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

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

本指南展示了如何使用代码中的驱动程序活动信息。如果您想了解如何记录驱动程序中的事件,请考虑阅读我们的日志记录指南.

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

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

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

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

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

  • 命令事件

  • 服务器发现和监控事件

  • 连接池事件

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

要查看可以监控的所有事件的完整列表,请参阅MongoDB Java驱动的MongoDB事件包。

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

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

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

注意

内部命令

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

重要

被编辑的输出

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

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

要创建一个计数器,请执行以下操作

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

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

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

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

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

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

MongoClientSettings settings =
MongoClientSettings.builder()
.applyConnectionString(URI)
.addCommandListener(new CommandCounter())
.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run some commands to test the timer
collection.find().first();
collection.find().first();
mongoClient.close();

前面的代码片段生成的输出类似于以下内容

{find=1}
{find=2}
{find=2, endSessions=1}

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

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

驱动器定义了九个SDAM事件。驱动器将这九个事件分为三个不同的监听器接口,每个接口监听九个事件中的三个。以下是这三个接口及其监听的事件

  • ClusterListener:[相关事件链接](https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#topology) related events

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

  • ServerMonitorListener:心跳相关的事件

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

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

注意

负载均衡模式

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

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

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

class IsWriteable 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类。

IsWriteable clusterListener = new IsWriteable();
MongoClientSettings settings =
MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToClusterSettings(builder ->
builder.addClusterListener(clusterListener))
.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger a ClusterDescriptionChangedEvent event
collection.find().first();

前面的代码片段生成的输出类似于以下内容

Able to write to server

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

连接池事件是与驱动器持有的连接池相关的事件。连接池是驱动程序与MongoDB实例保持的一组打开的TCP连接。连接池有助于减少应用程序与MongoDB实例进行网络握手所需的次数,并有助于提高应用程序的运行速度。

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

此示例展示了如何创建一个监听器类,每当从连接池中检查出连接时,都会打印一条消息。

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

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

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

ConnectionPoolLibrarian cpListener = new ConnectionPoolLibrarian();
MongoClientSettings settings =
MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToConnectionPoolSettings(builder ->
builder.addConnectionPoolListener(cpListener))
.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger connection pool events
collection.find().first();

前面的代码片段生成的输出类似于以下内容

Let me get you the connection with id 21...

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

您可以使用 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 是一个与 JMX 兼容的 GUI 监控工具,包含在 Java 平台之中。

提示

查阅官方 JMX 和 JConsole 文档

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

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

JMXConnectionPoolListener connectionPoolListener = new JMXConnectionPoolListener();
MongoClientSettings settings =
MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToConnectionPoolSettings(builder -> builder.addConnectionPoolListener(connectionPoolListener))
.build();
// Creates a MongoClient instance that enables connection pool event monitoring with the JMX tool
MongoClient mongoClient = MongoClients.create(settings);
try {
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);
// Prints exception details if any exceptions occur during the code execution
} catch (Exception e) {
e.printStackTrace();
}

前面的代码片段生成的输出类似于以下内容

Navigate to JConsole to see your connection pools...

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

jconsole

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

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

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

  3. 点击 MBeans 选项卡。

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

当您不再想使用 JConsole 检查连接池时,请执行以下操作

  • 通过关闭 JConsole 窗口退出 JConsole

  • 停止运行前代码片段的 Java 程序

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

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

如果您使用的是 分布式追踪系统,您可以包含来自驱动器的事件数据。分布式追踪系统是一种应用,用于跟踪在面向服务的架构中请求如何在不同的服务间传播。

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

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

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

要查看分布式追踪系统的详细描述,请参阅Google Research的Dapper

返回

日志记录