Docs 菜单
Docs 主页
/ / /
Java (Sync) 驱动程序
/

监控

在此页面上

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

在本指南中,您可以了解如何在 MongoDB 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 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 对象中,并使用 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 实例或集群的状态变化相关的事件。

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

  • ClusterListener拓扑结构相关事件

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

  • ServerMonitorListener:与心跳有关的事件

如需监控 SDAM 事件类型,请编写实现上述 3 个接口之一的类,然后将该类的实例注册到您的 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
客户端生成的唯一标识符。当应用程序有多个 MongoClient 实例连接到同一 MongoDB 部署时,该标识符可确保驱动程序生成的每个 MXBean 都有唯一的名称。
host
运行 mongodmongos 进程的计算机的主机名。
port
mongodmongos 进程正在侦听的端口。
minSize
连接池的最小大小,包括空闲和正在使用的连接。
maxSize
连接池的最大大小,包括空闲连接和使用中的连接。
size
连接池的当前大小,包括空闲连接和使用中的连接。
checkedOutCount
当前正在使用的连接数。

此驱动程序创建的所有 MXBean 实例均位于 "org.mongodb.driver" 域中。

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

本例展示了如何使用 JMX 和 JConsole 监控驱动程序的连接池。JConsole 是 Java 平台自带的与 JMX 兼容的图形界面监控工具。

提示

查阅官方 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 后,在图形界面中执行以下操作:

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

  2. 在警告对话框中按 Insecure Connection(不安全连接)。

  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

后退

日志记录