文档菜单
文档首页
/ / /
Kotlin 协程
/

监控

在本页

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 命令事件

  • 服务器发现和监控事件

  • 连接池事件

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

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

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

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

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

注意

内部命令

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

重要

已编辑的输出

为了安全起见,驱动程序会抹去一些命令事件的全部内容。这保护了这些命令事件中包含的敏感信息。有关抹去的命令事件的完整列表,请参阅MongoDB 命令日志和监控规范。

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

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

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

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

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

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

class CommandCounter : CommandListener {
private val commands = mutableMapOf<String, Int>()
@Synchronized
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:与mongodmongos进程相关的事件

  • ServerMonitorListener:心跳相关事件

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

有关每个SDAM事件的详细描述,请参阅MongoDB SDAM监控事件规范。

本示例演示了如何创建一个监听器类,该类会打印一条消息,告知您是否可以写入您的MongoDB实例。

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

class IsWriteable : ClusterListener {
private var isWritable = false
@Synchronized
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文档

您可以使用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 是一个随 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中执行以下操作

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

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

  3. 点击 MBeans 选项卡。

  4. "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

返回

日志记录