监控
概述
在本指南中,您可以了解如何在MongoDB Kotlin驱动程序中设置和配置监控。
监控是获取正在运行的程序执行活动信息的过程,用于在应用程序或应用程序性能管理库中。
监控MongoDB Kotlin驱动程序让您了解驱动程序的资源使用情况和性能,并有助于您在设计调试应用程序时做出明智的决定。
在本指南中,您将学习如何执行以下任务
本指南展示了如何在代码中使用关于驱动程序活动信息。如果您想了解如何在驱动程序中记录事件,请考虑阅读我们的日志记录指南.
监控事件
要监控事件,您必须在您的MongoClient
实例上注册一个监听器。
事件是发生在运行程序中的任何动作。驱动程序包括监听驱动程序运行时发生的事件子集的功能。
监听器是一个在特定事件发生时执行某些操作的类。监听器API定义了它可以响应的事件。
监听器类的每个方法代表对特定事件的响应。每个方法接收一个参数:一个表示方法响应的事件的对象。
MongoDB Kotlin 驱动将定义的事件组织成三个类别
命令事件
服务器发现和监控事件
连接池事件
以下部分展示了如何监控每个事件类别。
要查看您可以监控的所有事件的完整列表,请查看 MongoDB Kotlin 驱动的事件包。
命令事件
命令事件是与 MongoDB 数据库命令相关的事件。产生命令事件的一些数据库命令示例包括 find
、insert
、delete
和 count
。
要监控命令事件,编写一个实现了 CommandListener
接口的类,并将该类的实例注册到您的 MongoClient
实例。
有关 MongoDB 数据库命令的更多信息,请参阅MongoDB 手册中的数据库命令条目。
注意
内部命令
驱动程序不会为其内部调用的命令发布事件。这包括驱动程序用于监控您的集群的数据库命令以及与连接建立相关的命令(例如初始的 hello
命令)。
示例
以下示例展示了如何为数据库命令创建计数器。该计数器记录驱动程序成功执行每个数据库命令的次数,并在每次数据库命令完成后打印此信息。
要创建计数器,请执行以下操作
创建一个带有计数器功能的类,该类实现了
CommandListener
接口。将实现
CommandListener
接口的新类的实例添加到MongoClientSettings
对象中。使用
MongoClientSettings
对象配置一个MongoClient
实例。
以下代码定义了实现CommandListener
接口的CommandCounter
类。
class CommandCounter : CommandListener { private val commands = mutableMapOf<String, Int>() override fun commandSucceeded(event: CommandSucceededEvent) { val commandName = event.commandName val count = commands[commandName] ?: 0 commands[commandName] = count + 1 println(commands.toString()) } override fun commandFailed(event: CommandFailedEvent) { println("Failed execution of command '${event.commandName}' with id ${event.requestId}") } }
以下代码将CommandCounter
类的实例添加到MongoClientSettings
对象中,并使用MongoClientSettings
对象配置一个MongoClient
实例。然后,代码运行一些数据库命令以测试计数器。
val commandCounter = CommandCounter() val settings = MongoClientSettings.builder() .applyConnectionString(URI) .addCommandListener(commandCounter) .build() val mongoClient = MongoClient.create(settings) val database = mongoClient.getDatabase(DATABASE) val collection = database.getCollection<Document>(COLLECTION) // Run some commands to test the counter collection.find().firstOrNull() collection.find().firstOrNull()
{find=1} {find=2} {find=2, endSessions=1}
有关本节中提到的类和方法更多信息,请参阅以下API文档
服务器发现和监控事件
服务器发现和监控(SDAM)事件是与您连接的MongoDB实例或集群状态更改相关的事件。
驱动程序定义了九个SDAM事件。驱动程序将这些九个事件分为三个独立的监听器接口,每个接口监听九个事件中的三个。以下是三个接口及其监听的事件:
ClusterListener
:拓扑相关事件ServerListener
:与mongod
或mongos
进程相关的事件ServerMonitorListener
:心跳相关事件
要监控某种SDAM事件,编写一个实现前三个接口之一的类,并将该类的实例注册到您的MongoClient
实例。
有关每个SDAM事件的详细描述,请参阅MongoDB SDAM监控事件规范。
示例
本示例演示了如何创建一个监听器类,该类会打印一条消息,告知您是否可以写入您的MongoDB实例。
以下代码定义了一个实现ClusterListener
接口的IsWritable
类。
class IsWriteable : ClusterListener { private var isWritable = false override fun clusterDescriptionChanged(event: ClusterDescriptionChangedEvent) { if (!isWritable) { if (event.newDescription.hasWritableServer()) { isWritable = true println("Able to write to cluster") } } else { if (!event.newDescription.hasWritableServer()) { isWritable = false println("Unable to write to cluster") } } } }
以下代码将IsWritable
类的实例添加到MongoClient
对象中。然后代码运行一个查找操作来测试IsWritable
类。
val clusterListener = IsWriteable() val settings = MongoClientSettings.builder() .applyConnectionString(URI) .applyToClusterSettings { builder -> builder.addClusterListener(clusterListener) } .build() val mongoClient = MongoClient.create(settings) val database = mongoClient.getDatabase(DATABASE) val collection = database.getCollection<Document>(COLLECTION) // Run a command to trigger a ClusterDescriptionChangedEvent event collection.find().firstOrNull()
Able to write to server
有关本节中提到的类和方法更多信息,请参阅以下API文档
连接池事件
连接池事件是与驱动程序持有的连接池相关的事件。连接池是驱动程序与MongoDB实例保持的打开TCP连接的集合。连接池有助于减少应用程序与MongoDB实例需要执行的握手次数,并有助于提高应用程序的运行速度。
要监控连接池事件,编写一个实现ConnectionPoolListener
接口的类,并将该类的实例注册到您的MongoClient
实例中。
示例
此示例演示了如何创建一个监听器类,每次从连接池中取出连接时都会打印一条消息。
以下代码定义了一个实现ConnectionPoolListener
接口的ConnectionPoolLibrarian
类。
class ConnectionPoolLibrarian : ConnectionPoolListener { override fun connectionCheckedOut(event: ConnectionCheckedOutEvent) { println("Let me get you the connection with id ${event.connectionId.localValue}...") } override fun connectionCheckOutFailed(event: ConnectionCheckOutFailedEvent) { println("Something went wrong! Failed to checkout connection.") } }
以下代码将ConnectionPoolLibrarian
类的一个实例添加到一个MongoClient
对象中。然后运行一个数据库命令来测试图书管理员。
val cpListener = ConnectionPoolLibrarian() val settings = MongoClientSettings.builder() .applyConnectionString(URI) .applyToConnectionPoolSettings { builder -> builder.addConnectionPoolListener(cpListener) } .build() val mongoClient = MongoClient.create(settings) val database = mongoClient.getDatabase(DATABASE) val collection = database.getCollection<Document>(COLLECTION) // Run a command to trigger connection pool events collection.find().firstOrNull()
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 是一个随 Java 平台一起提供的符合 JMX 规范的 GUI 监控工具。
提示
参考官方 JMX 和 JConsole 文档
此示例中对 JMX 和 JConsole 的描述仅供参考,而非事实依据。为确保信息的准确性,请参考以下官方 Oracle 资源
以下代码片段向一个 MongoClient
实例添加了一个 JMXConnectionPoolListener
。然后代码会暂停执行,以便您可以导航到JConsole并检查您的连接池。
val connectionPoolListener = JMXConnectionPoolListener() val settings = MongoClientSettings.builder() .applyConnectionString(uri) .applyToConnectionPoolSettings { it.addConnectionPoolListener(connectionPoolListener) } .build() val mongoClient: MongoClient = MongoClient.create(settings) try { println("Navigate to JConsole to see your connection pools...") Thread.sleep(Long.MAX_VALUE) } catch (e: Exception) { e.printStackTrace() }
Navigate to JConsole to see your connection pools...
启动您的服务器后,使用以下命令在终端中打开JConsole
jconsole
JConsole打开后,在GUI中执行以下操作
选择运行前面示例代码的进程。
按下不安全连接 在警告对话框中。
点击 MBeans 选项卡。
在
"org.mongodb.driver"
域下检查您的连接池事件。
当您不再想使用JConsole检查连接池时,请执行以下操作
通过关闭JConsole窗口退出JConsole
停止运行前面代码片段的程序
有关JMX和JConsole的更多信息,请参阅以下Oracle资源
有关 JMXConnectionPoolListener
类的更多信息,请参阅JMXConnectionPoolListener。
将驱动器包含在您的分布式跟踪系统中
如果您使用的是 分布式跟踪系统,则可以将驱动器的事件数据包含在内。分布式跟踪系统是一个跟踪请求如何在面向服务的架构中传播到不同服务的应用程序。
如果您在一个Spring Cloud应用程序中使用驱动程序,请使用Spring Cloud Sleuth将MongoDB事件数据包含到Zipkin分布式跟踪系统中。
如果您不使用Spring Cloud或者需要将驱动事件数据包含在除了Zipkin之外的分布式跟踪系统中,您必须编写一个命令事件监听器来管理您所需分布式跟踪系统的span。要查看此类监听器的实现,请参阅Spring Cloud Sleuth源代码中的spans类的Java源代码。
要了解更多关于Spring Cloud Sleuth的信息,请参阅Spring Cloud Sleuth文档中的入门指南。
要查看分布式追踪系统的详细描述,请参阅Google Research的Dapper。