FAQ
在此页面上
本页包含常见问题及其相应解答。
提示
如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解后续步骤和更多资源。
为什么连接 MongoDB 时会出错?
如果在连接到 MongoDB 部署时出现问题,请参阅连接故障排除指南,了解潜在的解决方案。
Go 驱动程序中的连接池化是如何工作的?
Client
对于MongoDB拓扑结构中的每个服务器,每个 实例都有一个内置连接池。连接池按需打开套接字以支持应用程序中的并发MongoDB操作或 goroutine 。
每个连接池的最大大小由 maxPoolSize
选项设置,默认值为 100
。如果某个服务器的在用连接数达到 maxPoolSize
值,则对该服务器的下一个请求将等待,直到出现可用连接。
Client
实例为 MongoDB 拓扑结构中的每台服务器打开两个额外的套接字,用于监视服务器状态。
例如,连接到 3 节点副本集的客户端会打开 6 个监控套接字。它还打开必要的套接字,支持应用程序在每个服务器上的并发操作,最大并发数为 maxPoolSize
。如果 maxPoolSize
为 100
,并且应用程序仅使用主节点(默认值),则仅主节点连接池增长,总连接数最多可为 106
。如果应用程序使用读取偏好来查询从节点,则其连接池会增长,总连接数可以为 306
。
此外,连接池受速率限制,因此每个连接池在任何时候最多只能并行创建 maxConnecting
个连接的值。在以下情况下,任何额外的 goroutine 都会停止等待:
其中一个现有的 goroutines 完成创建连接,或者一个现有的连接被退回到池中。
由于对创建连接的速率有限制,驱动程序重用现有连接的能力得到了提高。
您可以使用 minPoolSize
选项设置每个服务器的最小并发连接数量,此值默认为 0
。设置 minPoolSize
后,连接池将以此套接字数量进行初始化。如果由于任何网络错误导致套接字关闭,导致套接字总数(包括使用中的和闲置的)下降到最小值以下,则会打开更多套接字,直至达到最小值。
您可以使用maxIdleTimeMS
选项设置连接在被删除和替换之前在池中保持空闲状态的最大毫秒数,该选项默认为None
(无限制)。
以下 Client
的默认配置适用于大多数应用程序:
client := mongo.Connect(context.TODO(), "<connection string>")
为每个进程创建一个客户端,并在所有操作中重复使用。为每个请求创建一个新客户端是个常见的错误,效率非常低。
如要在一个进程中支持大量并发 MongoDB 操作,您可以增加 maxPoolSize
。一旦池达到其最大大小,其他操作就会等待套接字变得可用。
该驱动程序不限制可以等待套接字变为可用状态的操作数量,应用程序有责任在负载峰值期间将其池的大小限制为绑定队列。除非定义了 waitQueueTimeoutMS
选项,否则操作可以等待任何时间长度。
如果操作等待套接字的时间超过 waitQueueTimeoutMS
所定义的时长,则会引发连接错误。如果在负载峰值期间限制操作的持续时间比完成每个操作更重要,请使用此选项。
当 Client.Disconnect()
被任何 goroutine 调用时,驱动程序会关闭所有闲置套接字,并关闭所有正在使用的套接字,因为这些套接字会返回到池中。
如何修复“WriteNull 只能在定位于元素或值上时写入,但却定位在 TopLevel 上”错误?
bson.Marshal()
方法需要一个可解码为 BSON 文档的参数,例如bson.D
类型。 当您将 BSON 文档以外的内容传递给bson.Marshal()
时,会出现此错误。
当您将 null
传递给 bson.Marshal()
时会发生 WriteNull
错误。可能会发生类似错误的情况包括:
将字符串传递给
bson.Marshal()
,引起WriteString
错误。将布尔值传递给
bson.Marshal()
引发了WriteBoolean
错误。将整数传递给
bson.Marshal()
,会引起WriteInt32
错误。
当您执行内部使用bson.Marshal()
方法的 CRUD 操作或直接调用bson.Marshal()
对数据进行编码时,可能会遇到此错误。
以下代码会产生 WriteNull
错误,因为驱动程序无法在 FindOneAndUpdate()
操作期间将 sortOrder
的null
值编码为 BSON:
var sortOrder bson.D opts := options.FindOneAndUpdate().SetSort(sortOrder) updateDocument := bson.D{{"$inc", bson.D{{"counter", 1}}}} result := coll.FindOneAndUpdate(context.TODO(), bson.D{}, updateDocument, opts) if err := result.Err(); err != nil { panic(err) }
下方代码演示如何正确地将 sortOrder
变量初始化为 bson.D
类型,以便驱动程序可以将其转换为 BSON:
sortOrder := bson.D{}
如何将 BSON 文档转换为 JSON?
驱动程序提供了多种可用于将 BSON 文档转换为 JSON 的封送拆收器方法,例如MarshalExtJSON()
方法。 若要查看 JSON 编码的可读形式,必须使用解组器方法或字符串类型转换来解析 JSON 字节格式。
以下代码使用 MarshalExtJSON()
方法将 BSON 文档转换为 JSON,然后使用 string type-casting 解析并打印 JSON 字节数组:
bsonDocument := bson.D{{"hello", "world"}} jsonBytes, err := bson.MarshalExtJSON(bsonDocument, true, false) if err != nil { panic(err) } fmt.Println(string(jsonBytes))
{"hello":"world"}
要了解有关 BSON 和 Go 类型之间转换的更多信息,请参阅使用 BSON 指南。