监控您的部署
概述
在本指南中,您可以了解如何在 Java 反应式流驱动程序中设置和配置 监控。
监控是收集有关运行程序执行活动的信息的过程,用于在应用程序或应用程序性能管理库中使用。
监控 MongoDB Java 驱动程序可以帮助您了解驱动程序的资源使用和性能,并有助于您在设计和应用调试时做出明智的决定。
在本指南中,您将学习如何执行以下任务
监控事件
要监控一个事件,您必须在您的MongoClient
实例上注册一个监听器。
事件是运行中的程序发生的任何动作。驱动程序包括在驱动程序运行时监听发生的事件子集的功能。
监听器是在某些事件发生时执行某些操作的类。监听器的API定义了它可以响应的事件。
监听器类的每个方法代表对某个事件的响应。每个方法接收一个参数:一个代表该方法响应的事件的对象。
MongoDB Java驱动程序将其定义的事件组织成三个类别
命令事件
服务器发现和监控事件
连接池事件
以下各节将展示如何监控每个事件类别。
有关您可以监控的所有事件的完整列表,请查看MongoDB Java驱动程序的事件包。
命令事件
命令事件是与MongoDB数据库命令相关的事件。一些会产生命令事件的数据库命令示例包括:find
、insert
、delete
和count
。
要监控命令事件,创建一个实现CommandListener
接口的类,并将该类的实例注册到您的MongoClient
实例中。
有关MongoDB数据库命令的更多信息,请参阅MongoDB服务器手册中的数据库命令。
注意
内部命令
驱动程序不会为其内部调用的命令发布事件。这包括驱动程序用来监控您的集群的数据库命令以及与连接建立相关的命令(例如初始的hello
命令)。
示例
以下示例展示了如何为数据库命令创建计数器。该计数器记录驱动程序成功执行每个数据库命令的次数,并在每次数据库命令完成后打印此信息。
要实现计数器,请执行以下步骤
创建一个具有计数功能的类,实现
CommandListener
接口。将实现
CommandListener
的新类实例添加到MongoClientSettings
对象中。使用
MongoClientSettings
对象配置MongoClient
实例。
以下代码定义了实现CommandListener
接口的CommandCounter
类。
class CommandCounter implements CommandListener { private final Map<String, Integer> commands = new HashMap<String, Integer>(); 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); } 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
:与mongod
或mongos
进程相关的事件ServerMonitorListener
:心跳相关的事件
要监控某种SDAM事件,编写一个实现上述三个接口之一的类,并将该类的实例注册到您的MongoClient
实例中。
有关驱动程序中每个SDAM事件的详细描述,请参阅MongoDB SDAM 日志和监控规范。
示例
以下示例演示了如何创建一个监听器类,该类可以打印一条消息,告知您驱动程序是否可以写入您的MongoDB实例。
以下代码定义了一个实现ClusterListener
接口的IsWritable
类。
class IsWritable 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
类。
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 { public void connectionCheckedOut(final ConnectionCheckedOutEvent event) { System.out.printf("Fetching the connection with id %s...%n", event.getConnectionId().getLocalValue()); } 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...
使用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是Java平台附带的JMX兼容的GUI监控工具。
以下代码片段向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中执行以下操作
选择运行上述示例代码的Java进程。
点击不安全连接在警告对话框中。
点击MBeans标签页。
在
"org.mongodb.driver"
域下检查您的连接池事件。
当您不再需要使用JConsole检查连接池时,请执行以下任务
关闭JConsole窗口退出JConsole。
停止运行上述代码片段的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文档
有关本文档中提到的类和方法的更多信息,请参阅以下API文档