监控
概述
在本指南中,您可以了解如何在 MongoDB Java 驱动程序中设置和配置 监控。
监控是获取有关运行程序执行活动信息的过程,用于应用程序或应用程序性能管理库。
监控 MongoDB Java 驱动程序可以让您了解驱动程序的资源使用情况和性能,并有助于您在设计应用程序和调试应用程序时做出明智的决策。
在本指南中,您将学习如何执行以下任务
本指南展示了如何使用代码中的驱动程序活动信息。如果您想了解如何记录驱动程序中的事件,请考虑阅读我们的日志记录指南.
监控事件
要监控一个 事件,您必须在您的MongoClient
实例上注册一个 监听器。
事件是运行程序中发生的任何操作。驱动程序包括在驱动程序运行时监听发生事件子集的功能。
监听器是一个在特定事件发生时执行某些操作的类。监听器的 API 定义它可以响应的事件。
监听器类的每个方法都代表对某个事件的响应。每个方法接收一个参数:表示该方法响应的事件的对象。
MongoDB Java驱动将定义的事件组织成三个类别。
命令事件
服务器发现和监控事件
连接池事件
以下各节展示了如何监控每个事件类别。
要查看可以监控的所有事件的完整列表,请参阅MongoDB Java驱动的MongoDB事件包。
命令事件
命令事件是与MongoDB数据库命令相关的事件。产生命令事件的数据库命令示例包括find
、insert
、delete
和count
。
要监控命令事件,编写一个实现CommandListener
接口的类,并将该类的实例注册到您的MongoClient
实例中。
有关MongoDB数据库命令的更多信息,请参阅MongoDB手册中的数据库命令条目。
注意
内部命令
驱动程序不会为其内部调用的命令发布事件。这包括驱动程序用来监控您的集群的数据库命令和与连接建立相关的命令(如初始的hello
命令)。
示例
本示例展示了如何为数据库命令创建一个计数器。该计数器记录驱动程序成功执行每个数据库命令的次数,并在每次数据库命令完成后打印此信息。
要创建一个计数器,请执行以下操作
创建一个具有计数功能的类,该类实现了
CommandListener
接口。将实现
CommandListener
接口的新类的实例添加到MongoClientSettings
对象中。使用
MongoClientSettings
对象配置MongoClient
实例。
以下代码定义了实现CommandListener
接口的CommandCounter
类。
class CommandCounter implements CommandListener { private Map<String, Integer> commands = new HashMap<String, Integer>(); 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()); } 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 eventsServerListener
:与mongod
或mongos
进程相关的事件ServerMonitorListener
:心跳相关的事件
要监控SDAM事件类型,请编写一个实现前三个接口之一的类,并将该类的实例注册到您的MongoClient
实例中。
有关驱动程序中每个SDAM事件的详细描述,请参阅MongoDB SDAM 日志和监控规范。
示例
此示例展示了如何创建一个监听器类,它会打印一条消息,告知您驱动程序是否可以写入您的MongoDB实例。
以下代码定义了实现ClusterListener
接口的IsWritable
类。
class IsWriteable implements ClusterListener { private boolean isWritable; 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 { public void connectionCheckedOut(final ConnectionCheckedOutEvent event) { System.out.println(String.format("Let me get you the connection with id %s...", event.getConnectionId().getLocalValue())); } 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文档
使用JMX监控连接池事件
您可以使用 Java 管理扩展 (JMX) 来监控连接池事件。JMX 提供了监控应用程序和设备的工具。
有关 JMX 的更多信息,请参阅 Oracle 官方 JMX 文档。
JMX 支持
要启用 JMX 连接池监控,请将 JMXConnectionPoolListener
类的实例添加到您的 MongoClient
对象。
JMXConnectionPoolListener
类执行以下操作
为每个与驱动程序保持连接池的
mongod
或mongos
进程创建 MXBean 实例。将这些 MXBean 实例注册到平台 MBean 服务器。
注册在平台 MBean 服务器上的 MXBean 具有以下属性
属性 | 描述 |
---|---|
clusterId | 客户端生成的唯一标识符。此标识符确保当应用程序有多个连接到同一 MongoDB 部署的 MongoClient 实例时,驱动程序创建的每个 MXBean 都有一个唯一的名称。 |
host | 运行 mongod 或 mongos 进程的机器的计算机名。 |
port | mongod 或 mongos 进程监听的端口。 |
minSize | 连接池的最小大小,包括空闲和正在使用的连接。 |
maxSize | 连接池的最大大小,包括空闲和正在使用的连接。 |
size | 当前连接池的大小,包括空闲和正在使用的连接。 |
checkedOutCount | 当前正在使用的连接数。 |
驱动程序创建的所有 MXBean 实例都在域名 "org.mongodb.driver"
下。
有关本小节讨论的主题的更多信息,请参阅以下来自 Oracle 的资源
JMX 和 JConsole 示例
本例展示了如何使用 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 中执行以下操作
选择运行前例代码的 Java 进程。
按不安全连接 在警告对话框中。
点击 MBeans 选项卡。
在
"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。