创建客户端
在此页面上
- 运用
Mongo::Client
- 区块语法
- 数据库选择
- 连接类型
- 独立运行的实例服务器连接
- 副本集连接
- 分片集群连接
- DirectConnection
- 负载均衡器连接
- MongoDB Atlas 连接
- 从 AWS Lambda 连接到 MongoDB Atlas
- SRV URI 注释
- 客户端选项
- Ruby 选项
- URI 选项
- 超时选项
server_selection_timeout
socket_timeout
connect_timeout
max_time_ms
wtimeout
- TLS 连接
- TLS 与 SSL 选项名称
- 启用 TLS 连接
- 指定客户端 TLS 证书
- 修改
SSLContext
- 指定 CA 证书
- OCSP 验证
- IPv4/IPv6 连接
- TCP Keepalive 配置
- 连接池化
- 与分叉服务器一起使用
- 手动处理进程分叉
- 故障排除
- 可重试读取
- 现代可重试读取
- 旧版可重试读取
- 禁用可重试读取
- 可重试写入 (Retryable Writes)
- 现代可重试写入
- 旧版可重试写入
- 禁用可重试写入
- 日志记录
- 更改记录器级别
- 截断
- 压缩
- 服务器 API 参数
- 开发配置
- 生产配置
- 功能标志
运用 Mongo::Client
要连接到 MongoDB 部署,请创建一个Mongo::Client
对象。 向“Mongo::Client”构造函数提供主机和选项列表或 连接string URI 。 客户端选择的数据库默认为admin
。
默认,驱动程序将自动检测部署使用的拓扑结构并进行适当连接。
要连接到本地独立运行的 MongoDB 部署,请指定服务器的主机和端口。 在大多数情况下,您还需要指定要连接的数据库名称;如果未指定数据库名称,客户端将使用admin
数据库:
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017/mydb")
注意
主机名localhost
由驱动程序特殊处理,并且仅解析为 IPv4 地址。
要连接到 MongoDB Atlas ,请指定 Atlas 部署 URI:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/mydb?w=majority")
驱动程序将发现集群中的所有节点,并根据需要连接到这些节点。
区块语法
创建 Mongo::Client 对象的另一种方法是使用区块语法:
Mongo::Client.new(...) do |client| # work with the client end
请注意,使用此语法创建客户端时,客户端将在区块执行完成后自动关闭。
数据库选择
默认情况下,客户端将连接到admin
数据库。
admin
数据库是 MongoDB 中的特殊数据库,通常用于管理任务并存储用户和角色等管理数据(尽管用户和角色也可能在其他数据库中定义)。 在分片集群中, admin
数据库存在于配置服务器上,而不是分片服务器上。 虽然可以使用admin
数据库进行普通操作(例如存储应用程序数据),但不建议这样做,应用程序应显式指定它希望使用的数据库。
可以在Client
构造期间指定数据库:
# Using Ruby client options: client = Mongo::Client.new(['localhost'], database: 'mydb') # Using a MongoDB URI: client = Mongo::Client.new('mongodb://localhost/mydb')
给定一个Client
实例,可以调用use
方法来获取配置有指定数据库的新Client
实例:
client = Mongo::Client.new(['localhost'], database: 'mydb') admin_client = client.use('admin') # Issue an administrative command admin_client.database.command(replSetGetConfig: 1).documents.first
MongoDB 中还有其他特殊数据库,这些数据库只能用于其声明的用途:
连接类型
默认情况下,驱动程序将发现指示其连接到的部署类型(负载均衡部署除外),并以与部署类型匹配的方式运行。 以下小节介绍了驱动程序在每种部署类型中的行为方式,以及如何绕过自动部署类型检测,强制执行特定行为。
请注意,当驱动程序收到来自指示其连接的任何服务器的第一个回复时,就会检测到部署类型(除非请求了负载均衡模式,请参阅下文)。 即使底层部署被替换为其他类型的部署,驱动程序仍将保留在已发现或已配置的拓扑结构中。In particular, when replacing a replica set with a sharded cluster at the same address the client instance must be recreated (such as by restarting the application) for it to communicate with the sharded cluster.
目前不支持自动发现负载均衡部署。 负载均衡部署将被视为其底层类型的部署,通常是分片集群。 将负载均衡部署视为分片集群时,驱动程序将无法正确运行,因此,当部署为负载均衡部署时,必须显式配置客户端以连接到负载均衡器。
独立运行的实例服务器连接
如果部署是单个服务器(也称为独立运行的实例部署),则所有操作都将定向到指定的服务器。
如果服务器关闭并替换为副本集节点,则驱动程序将继续向该节点发送所有操作,即使该节点是从节点或将成为从节点。
要强制建立独立连接,请参阅下面的直接连接部分。
副本集连接
连接到副本集时,只需将副本集集中任何节点的解决传递给驾驶员即可。 该节点不一定是主节点 (primary node in the replica set)节点,也可以是隐藏节点。 然后,驾驶员将自动发现剩余节点。
但是,建议指定属于副本集的所有节点,以便在一个或多个节点不可用的情况下(例如,由于维护或重新配置)驱动程序仍然可以连接到副本集。
副本集连接示例:
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb') Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb")
要使驱动程序在连接时验证副本集设置名称,请使用replica_set
Ruby 选项或replicaSet
URI 选项进行传递:
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', replica_set: 'myapp') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?replicaSet=myapp")
如果部署不是副本集或使用不同的副本集名称,则所有操作都将失败(直到服务器返回预期的副本集)。
也可以在不指定设置名称的情况下强制建立副本连接。通常没有必要这样做,已弃用:
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', connect: :replica_set) # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=replica_set")
要连接到作为副本集部署的 MongoDB Atlas 集群,请连接到 URI:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority")
如果使用 SRV URI,请查看SRV URI 说明。
分片集群连接
要连接到分分片集群部署,请指定mongos
路由器的地址:
Mongo::Client.new([ '1.2.3.4:27017', '1.2.3.5:27017' ], database: 'mydb') Mongo::Client.new("mongodb://1.2.3.4:27017,1.2.3.5:27017/mydb")
请注意,与副本集连接不同,您可以选择连接到部署中存在的mongos
路由器的子集。 驱动程序将监控每个路由器并使用可用的路由器(即,驱动程序通常会处理由于故障或维护而变得不可用的单个路由器)。 显式指定路由器列表时,驱动程序不会发现可能配置的其余路由器,也不会尝试连接到这些路由器。
驱动程序将自动平衡其识别的路由器之间的操作负载。
要连接到作为分片集群部署的 MongoDB Atlas cluster,请连接到 URI:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority")
当驱动程序通过 SRV URI 连接到分片集群时,它将定期轮询 URI 中指定地址的 SRV 记录是否有更改,并自动在其服务器列表中添加和删除mongos
主机,因为它们是添加到分片集群或从分片集群中删除。
要强制建立分片集群连接,请使用connect: :sharded
选项。 通常没有必要这样做,已弃用:
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', connect: :sharded) # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=sharded")
如果使用 SRV URI,请查看SRV URI 说明。
DirectConnection
要禁用部署类型发现并强制所有操作在特定服务器上执行,请指定direct_connection
选项:
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', direct_connection: true) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?directConnection=true")
或者,已弃用的connect: :direct
选项是等效的:
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', connect: :direct) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?connect=direct")
直接连接模式对于在特定副本集节点上执行操作最有用,尽管它也允许底层服务器更改类型(例如从副本集节点更改为mongos
路由器,反之亦然)。
负载均衡器连接
与其他部署类型不同,驱动程序当前不会自动检测负载均衡部署。
要连接到负载均衡器,请指定load_balanced: true
Ruby 选项或loadBalanced=true
URI 选项:
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', load_balanced: true) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true")
使用这些选项时,如果指定的服务器不是负载均衡器,则客户端的所有操作都将失败(直到该服务器成为负载均衡器)。
要在服务器未标识为负载均衡器的情况下将其视为负载均衡器,请使用connect: :load_balanced
Ruby 选项或connect=load_balanced
URI 选项:
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', load_balanced: true, connect: :load_balanced) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true&connect=load_balanced")
MongoDB Atlas 连接
要连接到 Atlas 上的 MongoDB 部署,请先使用集群的连接字符串和其他客户端选项创建一个Mongo::Client
实例。
您可以将stable API版本设置为客户端选项,以避免升级到新服务器版本时发生重大更改。
以下代码展示了在连接到 MongoDB 部署时,如何指定连接字符串和 Stable API 客户端选项,并检查连接是否成功:
require 'mongo' # Replace the placeholders with your credentials uri = "mongodb+srv://<username>:<password>@cluster0.sample.mongodb.net/?retryWrites=true&w=majority" # Set the server_api field of the options object to Stable API version 1 options = { server_api: { version: "1" } } # Create a new client and connect to the server client = Mongo::Client.new(uri, options) # Send a ping to confirm a successful connection begin admin_client = client.use('admin') result = admin_client.database.command(ping: 1).documents.first puts "Pinged your deployment. You successfully connected to MongoDB!" rescue Mongo::Error::OperationFailure => ex puts ex ensure client.close end
从 AWS Lambda 连接到 MongoDB Atlas
要了解如何从 AWS Lambda 连接到 Atlas,请参阅使用 AWS Lambda 管理连接文档。
SRV URI 注释
当驱动程序连接到mongodb+srv 协议URI 时,请记住以下几点:
SRV URI 查找在构造客户端时同步执行。 如果此查找因任何原因失败,客户端构建将失败并出现异常。 当使用主机列表构造客户端时,只要客户端对象存在,驱动程序就会尝试联系和监控这些主机。 如果其中一个主机最初无法解析,但后来变为可解析,则驱动程序将能够在此类主机可用时与该主机建立连接。 初始 SRV URI 查找必须一次尝试成功;驱动程序将根据需要重试后续主机查找。
驱动程序在与 SRV 记录相对应的 DNS TXT 记录中查找 URI 选项。 这些选项可以按 URI 中指定的 URI 选项和 Ruby 选项的顺序覆盖。
由于 URI 选项是在与 SRV 查找分开的单独 DNS 查询中检索的,因此在网络连接不可靠的环境中,当 SRV 查找成功时,URI 选项查询可能会失败。 此类故障会导致驱动程序使用错误的身份验证源,从而导致身份验证失败。 可以通过显式指定身份验证源来解决这个问题:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority&authSource=admin") 如果构造的
Client
对象的拓扑结构未知或是分片集群,则驱动程序将开始监控指定的 SRV DNS 记录是否有更改,并自动更新集群中的服务器列表。如果拓扑结构变为单个或副本集,则更新将停止。
客户端选项
Mongo::Client
的构造函数接受许多配置驱动程序行为的选项。 这些选项可以在选项哈希中作为 Ruby 选项提供,在 URI 中作为 URI 选项提供,或两者兼而有之。 如果同时提供了 Ruby 选项和类似的 URI 选项,则 Ruby 选项优先。
Ruby 选项
注意
直接传递的选项应该是符号。
注意
除非另有说明,否则处理时间的 Ruby 选项以秒为单位。
选项 | 说明 | 类型 | 默认 | ||||||
---|---|---|---|---|---|---|---|---|---|
:app_name | 在服务器版本 >= 3.4 中建立连接时打印到 mongod 日志的应用程序名称。 | String | 无 | ||||||
:auth_mech | 指定要使用的身份验证机制。 可以是以下值之一: :gssapi 、 :mongodb_cr 、 :mongodb_x509 、 :plain 、 :scram 、 :scram256 。 GSSAPI (Kerberos) 身份验证需要额外的依赖项。 | Symbol | 如果未提供用户档案,则 nil . 如果提供了用户凭证,则默认值取决于服务器版本。 MongoDB 4.0 及更高版本:如果用户档案对应于支持:scram256 SCRAM-SHA-256 身份验证的用户,则为:scram ,否则为 。MongoDB 3.0-3.6: :scram 。 MongoDB 2.6: :mongodb_cr | ||||||
:auth_mech_properties | 提供其他身份验证机制属性。 属性中的键不区分大小写。 创建客户端时,密钥为小写。 | Hash | 使用 GSSAPI 身份验证机制时,默认属性为 {service_name: "mongodb"} 。 否则默认值为 nil。 | ||||||
:auth_source | 指定身份验证源。 | String | 对于 MongoDB 2.6 及更高版本:如果提供了档案,则为admin ,否则为当前数据库 | ||||||
:auto_encryption_options | 用于配置自动加密的
有关格式化这些选项的更多信息,请参阅客户端加密教程中的“自动加密选项”部分。 | Hash | 无 | ||||||
:bg_error_backtrace | 实验性的。 控制当背景线程中发生错误时是否以及如何记录回溯。如果为 true ,驱动程序将记录完整的回溯。 如果设置为正整数,则驱动程序将记录最多那么多的回溯行。 如果设置为false 或nil ,则不会记录任何回溯。 其他值均会出错。 | true , false , nil , Integer | 无 | ||||||
:compressors | 要使用的潜在压缩器列表(按优先顺序排列)。 有关驱动程序如何实现压缩的详细信息,请参阅下文。 | Array<String> | 无 | ||||||
:connect | 已弃用。 禁用通常由驱动程序执行的部署拓扑结构发现,并强制集群结构为特定类型。有效值为 :direct 、 :load_balanced 、 :replica_set 或:sharded 。 如果使用:load_balanced ,则客户端的行为就像已连接到负载均衡器一样,无论其连接的服务器是否将自身公布为负载均衡器。 | Symbol | 无 | ||||||
:connect_timeout | 引发异常之前等待建立套接字连接的秒数。 此超时还用于 SRV DNS 记录解析。 nil 和0 平均值无超时。如果传递了无效的超时值(例如负值或非数字值),则创建客户端将失败并显示错误。 | Float | 10 | ||||||
:database | 要连接的数据库的名称。 | String | 管理员 | ||||||
:direct_connection | 直接连接到指定主机,不发现部署拓扑结构。 | Boolean | false | ||||||
:heartbeat_frequency | 服务器监控器异步刷新服务器状态的秒数。 | Float | 10 | ||||||
:id_generator | 用于生成文档 ID 的自定义对象。 必须响应#generate。 | Object | 无 | ||||||
:load_balanced | 是否期望连接到负载均衡器。 | Boolean | false | ||||||
:local_threshold | 指定最近的服务器和可供选择进行操作的服务器之间的最大延迟(以秒为单位)。 | Float | 0.015 | ||||||
:logger | 自定义记录器。 | Object | Logger | ||||||
:max_connecting | 连接池尝试并行建立的最大连接数。 | Integer | 2 | ||||||
:max_idle_time | 连接在被连接池关闭之前可以处于空闲状态的最长时间(以秒为单位)。 Warning: when connected to a load balancer, the driver uses existing connections for iterating cursors (which includes change streams) and executing transactions. 通过此选项设置空闲时间可能会导致驱动程序关闭后续操作所需的连接,从而导致这些操作失败。 | Integer | 无 | ||||||
:max_pool_size | 每个服务器连接池的最大大小。 将此选项设置为零会删除连接池的最大大小限制,允许其增长到任意数量的连接。 | Integer | 20 | ||||||
:max_read_retries | 使用旧版读取重试时的最大读取重试次数。设置为 0 可禁用旧版读取重试。 | Integer | 1 | ||||||
:max_write_retries | 使用旧版写入重试时的最大写入重试次数。设置为 0 可禁用旧版写入重试。 | Integer | 1 | ||||||
:min_pool_size | 每个服务器连接池中的最小连接数。 驱动程序将在背景建立连接,直到池包含这么多连接。 | Integer | 0 | ||||||
:monitoring | 监控对象。 | Object | 无 | ||||||
:password | 用于进行身份验证的用户的密码。 | String | 无 | ||||||
:platform | 在服务器版本 >= 3.4 中建立连接时打印到 mongod 日志的元数据中包含的平台信息。 | String | 无 | ||||||
:read | 将用于选择服务器的读取偏好模式和标签集指定为
如果提供了标签集,则它们必须是哈希数组。 如果服务器的标签与所提供的标签集中的任何一个哈希匹配,则服务器满足读取偏好(read preference)。 每个标签集都必须是哈希值,并且在用于服务器选择之前会在内部转换为 | Hash | { :mode => :primary } | ||||||
:read_concern | 指定读关注(read concern)选项。 唯一有效的键是 level ,其有效值为:local 、 :available 、 :majority 、 :snapshot 和:linearizable 。 | Hash | 无 | ||||||
:read_retry_interval | 重试读取 mongos 的时间间隔(以秒为单位)。 | Integer | 5 | ||||||
:replica_set | 连接到副本集时,这是用于筛选服务器的副本集的名称。 | String | 无 | ||||||
:retry_writes | 如果单声明写入操作因网络错误而失败,驱动程序会在连接到服务器版本 3.6+ 时自动重试一次。 | Boolean | true | ||||||
:sdam_proc | 由于客户端在构建完成后立即开始在后台监控部署,因此构建客户端然后在单独的语句中订阅SDAM事件可能会导致订阅者收不到某些 SDAM 事件。 传递一个 注意:当 | Proc | 无 | ||||||
:server_api | 请求的服务器 API 版本。 这是一个包含以下允许项的哈希值:- 请注意,服务器 API 版本只能指定为 Ruby 选项,而不能指定为 URI 选项,并且不能针对数据库和 collection 对象进行覆盖。 如果在客户端上更改服务器 API 版本(例如通过 | Hash | 无 | ||||||
:server_selection_timeout | 在引发异常之前等待选择适当的服务器来执行操作的秒数。 | Float | 30 | ||||||
:socket_timeout | 在引发异常之前等待在套接字上执行操作的秒数。 nil 和0 平均值无超时。如果传递了无效的超时值(例如负值或非数字值),则创建客户端将失败并显示错误。 | Float | 无 | ||||||
:srv_max_hosts | 驱动程序在分片拓扑结构中与之通信的 mongos 的最大数量。 如果该选项设置为 0,则没有最大 mongoses 数量限制。 如果给定 URI 解析的主机数量超过 :srv_max_hosts ,则客户端将随机选择:srv_max_hosts 大小的主机子集。 请注意,驱动程序在客户端构造期间忽略的主机将永远不会被使用。 如果驱动程序选择的主机不可用,则客户端将完全停止工作,即使部署具有其他功能正常的 mongos。 | Integer | 0 | ||||||
:srv_service_name | 要在 SRV DNS 查询中使用的服务名称。 | String | mongodb | ||||||
:ssl | 指示客户端通过 TLS 连接到服务器。 | Boolean | false | ||||||
:ssl_ca_cert | 包含串联的证书颁发机构证书的文件路径,用于验证从连接另一端传递的证书。 :ssl_verify 需要:ssl_ca_cert 、 :ssl_ca_cert_string 或:ssl_ca_cert_object 之一(按优先级顺序)。 | String | 无 | ||||||
:ssl_ca_cert_object | 表示证书颁发机构证书的 OpenSSL::X509::Certificate 数组,用于验证从连接另一端传递的证书。 :ssl_verify 需要:ssl_ca_cert 、 :ssl_ca_cert_string 或:ssl_ca_cert_object 之一(按优先级顺序)。 | Array< OpenSSL::X509::Certificate > | 无 | ||||||
:ssl_ca_cert_string | 包含连接的证书颁发机构证书的字符串,用于验证从连接另一端传递的证书。 :ssl_verify 需要:ssl_ca_cert 、 :ssl_ca_cert_string 或:ssl_ca_cert_object 之一(按优先级顺序)。 | String | 无 | ||||||
:ssl_cert | 用于向 MongoDB Server 标识应用程序的客户端证书文件的路径。该文件还可能包含证书的私钥;如果是这样,则该选项将忽略私钥。 该文件还可能包含形成从客户端证书到 CA 证书的证书链的中间证书;所有中间证书都将由驱动程序进行解析,并提供给 此选项(如果存在)优先于 | String | 无 | ||||||
:ssl_cert_object | OpenSSL::X509::Certificate 用于向 MongoDB Server 标识应用程序。通过此选项只能传递一个证书。 | OpenSSL::X509::Certificate | 无 | ||||||
:ssl_cert_string | 包含 PEM 编码证书的字符串,用于向 MongoDB Server 标识应用程序。该字符串还可能包含证书的私钥;如果是这样,则该选项将忽略私钥。 该字符串还可能包含形成从客户端证书到 CA 证书的证书链的中间证书;所有中间证书都将由驱动程序进行解析,并提供给 此选项(如果存在)优先于 | String | 无 | ||||||
:ssl_key | 用于识别针对 MongoDB 的连接的私钥文件。 请注意,即使密钥与证书存储在同一文件中,也需要显式指定两者。 此选项(如果存在)优先于 :ssl_key_string 和 :ssl_key_object 的值。 | String | 无 | ||||||
:ssl_key_object | 用于识别针对 MongoDB 的连接的私钥。 | OpenSSL::PKey | 无 | ||||||
:ssl_key_pass_phrase | 私钥的密码。 | String | 无 | ||||||
:ssl_key_string | 包含 PEM 编码私钥的字符串,用于识别针对 MongoDB 的连接。 此参数(如果存在)优先于选项 :ssl_key_object 的值。 | String | 无 | ||||||
:ssl_verify | 是否执行对等互连证书、主机名和 OCSP 端点验证。请注意,如果设置了 :ssl_verify_certificate ,则是否验证证书的决定将被覆盖;如果设置了:ssl_verify_hostname ,则是否验证主机名的决定将被覆盖;如果设置了:ssl_verify_ocsp_endpoint ,则是否验证 OCSP 端点的决定将被覆盖。 已设置。 | Boolean | true | ||||||
:ssl_verify_certificate | 是否执行对等互连证书验证。在是否执行证书验证方面,此设置会覆盖 :ssl_verify 设置。 | Boolean | true | ||||||
:ssl_verify_hostname | 是否执行对等互连主机名验证。此设置会覆盖有关是否执行主机名验证的 :ssl_verify 设置。 | Boolean | true | ||||||
:ssl_verify_ocsp_endpoint | 如果证书中指定了 OCSP 端点,是否根据证书中指定的 OCSP 端点验证服务器提供的证书。 在是否执行 OCSP 端点验证方面,此设置会覆盖 :ssl_verify。 | Boolean | true | ||||||
:truncate_logs | 是否按默认的 250 个字符截断日志。 | Boolean | true | ||||||
:user | 要进行身份验证的用户的名称。 | String | 无 | ||||||
:wait_queue_timeout | 等待连接池中的连接变为可用状态的秒数。 | Float | 10 | ||||||
:wrapping_libraries | 有关包装驱动程序的库(例如 ODM)的信息。 首先指定较低级别的库。 允许的哈希键::name、:version、:platform。 示例: [name: 'Mongoid', version: '7.1.2'] | Array<Hash> | 无 | ||||||
:write | 已弃用。 相当于 :write_concern 选项。 如果同时指定了:write 和:write_concern ,则它们的值必须相同。 | Hash | { w: 1 } | ||||||
:write_concern | 将写关注(write concern)选项指定为
| Hash | { w: 1 } | ||||||
:zlib_compression_level | 要使用的 Zlib 压缩级别(如果使用压缩)。 有关有效级别,请参阅 Ruby 的 Zlib 模块。 | Integer | 无 |
注意
Ruby 驱动程序不实施证书撤销列表 (CRL) 检查。
URI 选项
由于 URI 选项必须采用驼峰式大小写(这不是 Ruby 标准),因此下表显示了 URI 选项及其对应的 Ruby 选项。
注意
URI 中以毫秒为单位设置的选项在 Ruby 中表示为float
,单位为秒。
URI 选项 | Ruby 选项 |
---|---|
appName=String | :app_name => String |
authMechanism=String |
身份验证机制值按如下方式从 URI 选项转换为 Ruby 选项:
如果为身份验证机制提供了不同的值,则会将其转换为未修改的 Ruby 选项,并保留其 |
authMechanismProperties=Strings |
指定为以逗号分隔的键:值对,例如 |
authSource=String | :auth_source => String |
Compressors=Strings |
以逗号分隔的潜在要使用的压缩器列表,按优先顺序排列。 有关驱动程序如何实现压缩的详细信息,请参阅下文。 |
connect=String |
此处接受的值与 |
connectTimeoutMS=Integer |
与相应的 Ruby 选项不同,相应的 Ruby 选项因值无效(例如 负值和非数字值),通过此 URI 选项提供的无效值将被忽略,并显示警告。 |
directConnection=Boolean | :direct_connection => Boolean |
fsync=Boolean | { :write_concern => { :fsync => true|false }} |
heartbeatFrequencyMS=Integer | :heartbeat_frequency => Float |
journal=Boolean | { :write_concern => { :j => true|false }} |
loadBalanced=Boolean | :load_balanced => Boolean |
localThresholdMS=Integer | :local_threshold => Float |
maxConnecting=Integer | :max_connecting => Integer |
maxIdleTimeMS=Integer | :max_idle_time => Float |
maxStalenessSeconds=Integer |
如果 maxStalenessSeconds URI 选项值为 -1,则驱动程序会将其视为根本未给出该选项。 否则,如果选项值为数字,则 Ruby 选项将设置为转换为 |
maxPoolSize=Integer | :max_pool_size => Integer |
minPoolSize=Integer | :min_pool_size => Integer |
readConcernLevel=String | :read_concern => Hash |
readPreference=String | { :read => { :mode => Symbol }} |
readPreferenceTags=Strings |
readPreferenceTags 字段的每个实例都是逗号分隔的键:值对,将按照指定顺序出现在 :tag_sets 数组中。实例, |
replicaSet=String | :replica_set => String |
retryWrites=Boolean | :retry_writes => boolean |
serverSelectionTimeoutMS=Integer | :server_selection_timeout => Float |
socketTimeoutMS=Integer |
与相应的 Ruby 选项不同,相应的 Ruby 选项因值无效(例如 负值和非数字值),通过此 URI 选项提供的无效值将被忽略,并显示警告。 |
srvMaxHosts=Integer | :srv_max_hosts => Integer |
srvServiceName=String | :srv_service_name => String |
ssl=Boolean | :ssl => true|false |
tls=Boolean | :ssl => boolean |
tlsAllowInvalidCertificates=Boolean |
由于 |
tlsAllowInvalidHostnames=Boolean |
由于 |
tlsCAFile=String | :ssl_ca_cert => String |
tlsCertificateKeyFile=String | :ssl_cert => String |
tlsCertificateKeyFile=String | :ssl_key => String |
tlsCertificateKeyFilePassword=String | :ssl_key_pass_phrase => String |
tlsDisableOCSPEndpointCheck=Boolean |
由于 |
tlsInsecure=Boolean |
由于 tlsInsecure 使用 |
w=Integer|String | { :write_concern => { :w => Integer|String }} |
waitQueueTimeoutMS=Integer | :wait_queue_timeout => Float |
wtimeoutMS=Integer | { :write_concern => { :wtimeout => Integer }} |
zlibCompressionLevel=Integer | :zlib_compression_level => Integer |
注意
仅当 Ruby 驱动程序收到表明服务器证书已被撤销的最终签名响应时,才会导致连接失败。 因此,驱动程序无法识别tlsDisableCertificateRevocationCheck
URI 选项。 如果在 URI 中提供了此选项,它将被忽略。
超时选项
server_selection_timeout
执行操作时,等待驱动程序找到要向其发送操作的适当服务器的秒数。 Defaults to 30.
值为 0 表示无超时。
当通过 URI 选项传递无效值(例如负值或非数字值)时,无效输入将被忽略并显示警告。 当通过 Ruby 选项将无效值直接传递给客户端时,客户端构造会失败并显示错误。
在副本集部署中,应将此超时设置为超过典型的副本集选举时间,以便驱动程序透明地处理主节点更改。 此超时还允许应用程序和数据库同时启动;应用程序将等待这么多时间才能使数据库变得可用。
如果应用程序服务器位于反向代理后面,则服务器选择超时应小于反向代理上配置的请求超时(例如,这适用于 Heroku 上的部署,它在路由层具有 30 秒的固定超时)。 在开发过程中,可以降低此值,以便在服务器未运行时更快地失败。
socket_timeout
在常规(非监控)连接上等待套接字读取或写入完成的秒数。 默认为无超时。
值为 0 表示无超时。
当通过 URI 选项传递无效值(例如负值或非数字值)时,无效输入将被忽略并显示警告。 当通过 Ruby 选项将无效值直接传递给客户端时,客户端构造会失败并显示错误。
此超时应考虑网络延迟和操作持续时间。 例如,将此超时设置为 5 秒将使用Mongo::Error::SocketTimeoutError
中止在服务器上执行时间超过 5 秒的查询。
请注意,即使默认情况下没有设置套接字超时,操作系统仍可能根据其配置使读取操作超时。 keepalive 设置旨在检测断开的网络连接(而不是仅仅因为操作需要很长时间才能执行而中止操作)。
请注意,如果驱动程序的某个操作由于超过socket_timeout
值而超时,该操作不会在服务器上中止。 因此,建议对可能长时间运行的操作使用max_time_ms
选项,因为这会中止它们在服务器上的执行。
此选项不适用于监控连接。
connect_timeout
等待与服务器建立套接字连接的秒数。 默认为 10。
此超时还用作连接超时和套接字超时以监控连接。
When using a mongodb+srv://
URI, this timeout is also used for SRV and TXT DNS lookups. 请注意,超时适用于每次查找;由于 DNS 后缀搜索列表的原因,单个名称解析中可能会执行多次查找。
wait_queue_timeout
等待连接池中的连接变为可用状态的秒数。 默认为 10。
从驱动程序版本 2.11 开始,此超时应设置为至少与connect_timeout
一样大的值,因为连接池现在会在返回连接之前完全建立连接,这可能需要多次网络往返。
max_time_ms
作为特定操作的选项,指定允许在服务器上执行该操作的毫秒数。 默认未设置。
请考虑使用此选项而不是socket_timeout
,以便在服务器上可能长时间运行的操作花费太长时间时中断这些操作。
wtimeout
等待写操作被写关注(write concern)中指定数量的服务器确认的毫秒数。默认未设置,指示服务器应用其默认值。 此选项可在客户端上全局设置,也可传递给:write_concern
下的各个操作。
TLS 连接
要使用 TLS 连接到 MongoDB 部署,请执行以下操作:
在
Mongo::Client
中启用 TLS 连接。指定客户端 TLS 证书。
指定 CA 证书以验证服务器的 TLS 证书。
注意
使用 JRuby 时,当前不支持 ECDSA 证书。
TLS 与 SSL 选项名称
Ruby 驱动程序支持的所有 MongoDB 服务器版本(2.6 及更高版本)仅实现 TLS。 2.6 及更高版本的服务器不使用 SSL。
由于历史原因,与 TLS 配置相关的 Ruby 选项名称使用ssl
而不是tls
前缀。 Ruby 驱动程序的下一个主要版本 (3.0) 将使用tls
前缀作为 Ruby 选项名称。
URI 选项名称使用tls
前缀,但有一个例外: ssl
URI 选项已弃用,等同于tls
URI 选项。
启用 TLS 连接
当部署需要 TLS 连接时,必须在客户端显式请求 TLS - 目前无法自动检测部署是否需要 TLS。
要请求 TLS 连接,请在构造Mongo::Client
时指定以下客户端选项:
:ssl
Ruby 选项。tls
URI 选项。ssl
URI 选项(已弃用)。
指定客户端 TLS 证书
默认情况下,MongoDB Server 将尝试验证连接客户端的 TLS 证书,这要求客户端在连接时指定其 TLS 证书。 这可以通过以下方式完成:
:ssl_cert
/:ssl_cert_object
/:ssl_cert_string
和:ssl_key
/:ssl_key_object
/:ssl_key_string
/:ssl_key_pass_phrase
Ruby 选项。tlsCertificateKeyFile
URI 选项。
使用 Ruby 选项时,可能会单独提供客户端 TLS 证书和相应的私钥。 例如,如果证书存储在client.crt
中,私钥存储在client.key
中,则可以按如下方式构造Mongo::Client
:
client = Mongo::Client.new(["localhost:27017"], ssl: true, ssl_cert: 'path/to/client.crt', ssl_key: 'path/to/client.key', ssl_ca_cert: 'path/to/ca.crt', )
ssl_cert
ssl_cert_string
、 ssl_key
和ssl_key_string
Ruby 选项还允许分别在同一文件或字符串中提供证书和密钥。 同时包含证书和私钥的文件通常具有.pem
扩展名。 当在同一文件或字符串中提供证书和私钥时,必须同时使用证书和密钥选项,如下所示:
client = Mongo::Client.new(["localhost:27017"], ssl: true, ssl_cert: 'path/to/client.pem', ssl_key: 'path/to/client.pem', ssl_ca_cert: 'path/to/ca.crt', )
使用 URI 选项时,证书和密钥必须存储在一个文件中,并且必须存储在同一文件中。 用法示例:
client = Mongo::Client.new( "mongodb://localhost:27017/?tls=true&tlsCertificateKeyFile=path%2fto%2fclient.pem&tlsCertificateKeyFile=path%2fto%2fca.crt")
注意
URI 选项值必须正确进行 URI 转义。 例如,这适用于路径中的斜线。
修改 SSLContext
可能需要在驱动程序中进一步配置 TLS 选项,例如启用或禁用某些密码。 目前,Ruby 驱动程序不提供在初始化Mongo::Client
时执行此操作的方法。
但是,Ruby 驱动程序提供了一种设置全局“TLS 上下文钩子”的方法,这些钩子是用户提供的套接字使用的Proc``s that will be invoked before any TLS socket
connection and can be used to modify the underlying ``OpenSSL::SSL::SSLContext
对象。
要设置 TLS 上下文钩子,请添加Proc``s to the ``Mongo.tls_context_hooks
数组。 这应该在创建任何 Mongo::Client 实例之前完成。 例如,在 Rails 应用程序中,可以将此代码放在初始化程序中。
Mongo.tls_context_hooks.push( Proc.new { |context| context.ciphers = ["AES256-SHA"] } ) # Only the AES256-SHA cipher will be enabled from this point forward
Mongo.tls_context_hooks
中的每个Proc
都会传递一个OpenSSL::SSL::SSLContext
对象作为其唯一参数。 这些Proc``s will
be executed sequentially during the creation of every ``Mongo::Socket::SSL
对象。
可以分配调用Mongo.tls_context_hooks=
的整个钩子数组,但这样做会删除以前分配的所有钩子。 建议使用Array#push
或Array#unshift
方法添加新钩子。
还可以从Mongo.tls_context_hooks
中删除钩子,方法是在应用程序的其他位置存储对过程的引用,然后使用Array#delete_if
删除所需的钩子。
警告
TLS 上下文钩子是全局性的,会影响Mongo::Client
的每个实例。 任何允许应用程序启用这些钩子的库都应该公开修改钩子的方法(可以由应用程序调用),而不是在加载库时自动启用钩子。
有关为 TLS 配置MongoDB服务器的更多信息,请参阅MongoDB手册。
使用中间证书
可以将证书链用于客户端和服务器证书。 使用链时,应将证书颁发机构参数配置为仅包含受信任的根证书;中间证书(如有)应在服务器或客户端证书中提供,方法是分别将它们连接在叶服务器和客户端证书之后。
:ssl_cert
和:ssl_cert_string
Ruby 选项以及tlsCertificateKeyFile
URI 选项均支持证书链。 :ssl_cert_object
Ruby 选项,采用OpenSSL::X509::Certificate
的实例,不支持证书链。
Ruby 驱动程序执行严格的 X.509 证书验证,这要求在中间证书中设置以下两个字段:
X509v3 基本约束:CA: TRUE — 可以签署证书
X509v3 密钥用法:密钥证书签名 — 可以签署证书
有关这些标志 的更多信息,请参阅此 Stack Overflow 问题 。
将中间证书连接到tlsCAFile
/ ssl_ca_cert
选项中传递的根 CA 证书是一个常见的陷阱。 这样,中间证书就会提升到受信任状态,并且它们本身不会根据实际的 CA 根证书进行验证。 有关此问题的更多信息,请参阅 此邮件列表帖子 。
指定 CA 证书
默认情况下,驱动程序将尝试验证服务器的 TLS 证书,如果验证失败,将中止连接。 默认情况下,驱动程序将使用默认的系统根证书存储区作为信任锚。 要指定用于签署服务器证书的 CA 证书,请使用:
:ssl_ca_cert
/:ssl_ca_cert_string
/:ssl_ca_cert_object
Ruby 选项tlsCAFile
URI 选项。
如果给出了这些选项中的任何一个,则将仅根据指定的 CA 证书来验证服务器的证书,并且不会使用默认的系统根证书存储区。
要不执行服务器 TLS 证书验证(不建议这样做),请指定ssl_verify: false
Ruby 选项或tlsInsecure=true
URI 选项。
指定多个 CA 证书
:ssl_ca_cert
Ruby 选项和tlsCAFile
URI 选项可用于包含多个证书的文件。 如此引用的所有证书都将成为信任锚。
:ssl_ca_cert_object
选项接受一个证书数组,因此也可用于添加多个证书作为证书颁发机构。
:ssl_ca_cert_string
选项支持仅指定一个 CA 证书。
警告
不得在 CA 证书选项指定的文件中提供中间证书。 这样做会将中间证书提升为根证书,而不是根据根证书验证中间证书。
如果需要使用中间证书,请将其指定为客户端或服务器 TLS 证书文件的一部分。
OCSP 验证
如果服务器提供的证书包含 OCSP 端点 URI,则驱动程序将向指定端点发出 OCSP 请求,以验证证书的有效性。
可以通过在创建客户端时将:ssl_verify_ocsp_endpoint
Ruby 选项设置为false
或将tlsDisableOCSPEndpointCheck
URI 选项设置为true
来禁用 OCSP 端点检查。
注意
在 JRuby 上运行时,当前不执行 OCSP 端点检查,因为 JRuby 未正确公开 OCSP 端点 URI。
IPv4/IPv6 连接
当使用localhost
作为主机名构建客户端时,它将仅尝试 IPv4 连接(即,如果localhost
解析为127.0.0.1
和::1
,则驱动程序将仅尝试连接到127.0.0.1
)。
当使用localhost
以外的主机名构建客户端时,它将根据主机名解析的地址尝试 IPv4 和 IPv6 连接。 驱动程序遵循getaddrinfo
返回地址的顺序,并将尝试按顺序连接到这些地址。 将使用第一个成功的连接。
驱动程序当前未实现“Happy Eyeballs”算法。
TCP Keepalive 配置
在系统配置和 Ruby 语言运行时允许的情况下,驱动程序会启用 TCP keepalive,并且对于下面列出的每个 keepalive 参数,如果可以确定系统值并且该值高于列出的驱动程序值:
tcp_keepalive_time
:120 秒tcp_keepalive_intvl
:10 秒tcp_keepalive_cnt
:9 个探测器
注意
从 JRuby 9.2.14.0 开始, JRuby 不实现设置 keepalive 参数所需的 API。 使用 JRuby 时,驱动程序将无法设置 keepalive 参数,系统配置将生效。
要使用较低的值,或在 JRuby 等不公开所需 API 的环境中更改参数,请按照 MongoDB诊断常见问题解答keepalive 部分 中的描述在系统级别调整参数 。
连接池化
Mongo::Client
实例在客户端连接的每个服务器上都有一个连接池。 该连接池按需创建连接,以支持应用程序发出的并发 MongoDB 操作。 连接没有线程关联性。
客户端实例为每个已知服务器打开一个额外的连接,用于监控服务器的状态。
每个连接池的大小上限为max_pool_size
,默认为 5 。当应用程序中的线程开始对 MongoDB 执行操作时,它会尝试从连接池中检索连接以发送该操作。 如果池中有可用连接,则会从池中取出连接并将其用于操作。 如果没有可用连接且池大小小于max_pool_size
,则会创建新连接。 如果所有连接都在使用中并且连接池已达到其最大大小,则该线程将等待另一个线程将连接返回到连接池。 如果max_pool_size
设置为零,则池中的最大连接数没有限制。
每个池对可以同时连接到服务器的连接数有限制。 此限制称为max_connecting
,默认为 2。如果当前连接到服务器的连接数达到此限制,池将等待连接尝试成功或失败,然后再尝试创建新连接。 如果您的应用程序有大量线程,您可能需要增加max_connecting
以避免线程等待连接建立。
线程等待连接变为可用状态的秒数是可配置的。 此设置名为wait_queue_timeout
,以秒为单位。 如果达到此超时时间,则会引发Timeout::Error
。 默认为 1 秒。
从驱动程序版本 2.11 开始,驱动程序会急切地创建不超过min_pool_size
设置的连接。 在驱动程序版本 2.11 之前,驱动程序始终按需创建连接。 在驱动程序的所有版本中,一旦建立连接,只要连接池大小不超过min_pool_size
,驱动程序就会将其保留在连接池中。
请注意,如果将min_pool_size
设置为大于零的值,则即使应用程序不执行从节点读取,驱动程序也会与副本集部署中的从节点建立一定数量的连接。 这些连接的目的是在主节点发生变化时提供更快的故障转移。
以下是估计多线程应用程序将打开的连接数的示例:连接到 3 节点副本集的客户端打开 3 个监控套接字。 它还根据需要打开任意数量的套接字,以支持多线程应用程序在每台服务器上的并发操作,最多max_pool_size
个。 如果应用程序仅使用主节点(默认),则只有主节点连接池会增长,并且连接总数最多为 8(主节点池的 5 个连接 + 3 个监控连接)。 如果应用程序使用读取偏好(read preference)来查询从节点,则它们的池也会增长,并且总连接可以达到 18 (5 + 5 + 5 + 3)。
Mongo::Client
的默认配置适用于大多数应用程序:
client = Mongo::Client.new(["localhost:27017"])
为每个进程创建一次此客户端,并在所有操作中重复使用。 为每个请求创建一个新客户端是一个常见的错误,效率非常低,也不是客户端的设计初衷。
要在一个进程中支持极高数量的并发 MongoDB 操作,请增加max_pool_size
:
client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200)
要支持在一个进程中共享同一客户端的极大量线程,请增加max_connecting
:
client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200, max_connecting: 10)
允许任意数量的线程等待连接变为可用状态,并且可以等待默认值(1 秒)或wait_queue_timeout
设置:
client = Mongo::Client.new(["localhost:27017"], wait_queue_timeout: 0.5)
当任何线程在客户端上调用#close
时,所有连接都会关闭:
client.close
请注意,使用上述区块语法创建客户端时,客户端将在区块完成执行后自动关闭。
与分叉服务器一起使用
注意
使用 Mongoid 的应用程序应遵循Mongoid 的“使用分叉服务器”文档。 以下指南面向直接使用 Ruby 驱动程序的应用程序。
在具有分叉 Web 服务器(例如 Puma)的 Web 应用程序中使用mongo Ruby驱动程序时,或者当应用程序以其他方式进行分叉时,每个进程(父进程和子进程)都必须有自己的客户端连接。 这是因为:
后台 Ruby 线程(例如 Ruby MongoDB 驱动程序用于监控连接状态的线程)不会传输到子进程。
网络套接字等文件描述符在父进程和子进程之间共享,这可能会导致 I/O 冲突。
关于 ( 1 ),如果您在分叉后没有在子进程上重新启动驱动程序的监控线程,尽管您的子进程最初可能会正常运行,但如果/当您的MongoDB 集群状态发生变化时,您最终会看到Mongo::Error::NoServerAvailable
异常,示例,由于网络错误或维护事件。
关于 ( 2 ),如果子进程重复使用父进程的文件描述符,您将看到Mongo::Error::SocketError
错误,并附带Errno::EPIPE: Broken pipe
和EOFError: end of file reached
等消息。
在 Web应用程序程序中使用Ruby驾驶员程序时,如果可能,我们建议不要在父进程中创建任何Mongo::Client
实例(在工作线程被分叉之前),而仅在工作线程中创建客户端实例。
手动处理进程分叉
某些高级使用案例,例如 Puma 的 fork_worker 选项 ,要求Mongo::Client
实例在父进程和子进程中都打开。在这种情况下,您必须手动处理客户端重新连接。
为此,在派生之前,请关闭父进程上的所有现有客户端连接。 这将防止父进程因子进程重复使用父进程的文件而出现网络和监控错误。
# Immediately before fork client.close
注意
调用Client#close
不会中断当前正在进行的数据库操作。 执行新操作时,客户端将自动重新连接。
然后,在分叉后,立即在新分叉的子进程中重新连接客户端,这将重新生成驱动程序的监控线程。
# Immediately after fork client.reconnect
大多数 Web 服务器都提供钩子,应用程序可以使用这些钩子在工作进程分叉时执行操作。 推荐的钩子是:
对于 Puma ,使用
before_fork
和on_refork
在父进程中关闭客户端,并使用on_worker_boot
在子进程中重新连接。对于 Unicorn 、
before_fork
关闭父进程中的客户端,after_fork
重新连接子进程中的客户端。对于 Passenger 、
starting_worker_process
重新连接子进程中的客户端(Passenger 似乎没有 prefork 钩子)。
有关更多示例,请参阅Mongoid 的“使用分叉服务器”文档。
故障排除
客户端的summary
方法返回客户端的当前状态,包括客户端正在监控的服务器及其状态。 如果有任何服务器未被监控,则由NO-MONITORING
标志表示。
正常运行的客户端将生成类似于以下内容的摘要:
client.summary => "#<Client cluster=#<Cluster topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f] servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"
缺少后台线程的客户端将生成类似于以下内容的摘要:
client.summary => "#<Client cluster=#<Cluster topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f] servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"
可重试读取
驱动程序实现两种重试读取的机制:现代和旧版。从驱动程序版本 2.9.0 开始,旧版使用现代机制,并且默认已弃用。
现代可重试读取
使用现代机制时,如果出现网络错误、"非主节点"错误或"节点正在恢复"错误,则会重试一次读取操作。其中涵盖以下操作:
Collection#find和相关方法
变更流助手: Collection#watch 、 Database#watch 、 Client#watch
枚举命令: Client#list_mongo_databases 、 Client#list_databases 、 Client#database_names 、 Database#collection_names 、 Database#collections 、 Database#list_collections 、 Collection#indexes
当操作返回游标时,只能重试初始读取命令。 2.9.0 或更高版本的驱动程序不会重试游标上的getMore
操作。 此外,当重试读取操作时,会为该操作选择一个新的服务器;这可能会导致重试被发送到与接收第一次读取的服务器不同的服务器。
请注意,现代可重试读取只能用于 MongoDB 3.6 及更高版本的服务器。 与 MongoDB 3.4 及更低版本的服务器一起使用时,Ruby 驱动程序版本 2.9.0 及更高版本默认情况下不会重试读取 - 应用程序必须通过设置retry_reads: false
客户端选项或使用retryReads=false
URI 选项来显式请求传统可重试读取。
旧版可重试读取
通过设置retry_reads: false
客户端选项或将retryReads=false
URI 选项传递给客户端,可以使用 Ruby 驱动程序的传统读取重试行为。
使用旧版读取重试行为时,可以通过指定max_read_retries
客户端选项来设置重试次数。使用驱动程序版本 2.9.0 或更高版本时,使用传统可重试读取重试的操作集与上述针对现代可重试读取的操作集相同。 在较旧的驱动程序版本中,传统可重试写入的行为有所不同,因为某些操作不会重试。
从驱动程序版本 2.9.0 开始,旧版读取重试会在重试操作之前执行服务器选择,就像现代可重试写入一样。在较旧的驱动程序版本中,读取重试将发送到初始读取发送到的同一服务器。
禁用可重试读取
要禁用所有读取重试,请设置以下客户端选项: retry_reads: false, max_read_retries: 0
。
可重试写入 (Retryable Writes)
驱动程序实现两种重试写入的机制:现代和传统。 从驱动程序版本 2.9.0 开始,支持它的服务器默认使用现代机制,而旧版机制在所有服务器版本上均已弃用并默认禁用。
在对collection的日常操作中使用的以下写入方法会进行写入重试:
collection#insert_one
collection#update_one
collection#delete_one
collection#replace_one
collection#find_one_and_update
collection#find_one_and_replace
collection#find_one_and_delete
collection#bulk_write
(适用于所有单声明操作,即不适用于update_many
或delete_many
)
现代可重试写入
当驱动程序连接到 MongoDB 3.6 或更高版本的副本集或分片集群时,现代机制将重试失败的写入一次,因为它们需要服务器上的 oplog。 当驱动程序连接到独立的 MongoDB 服务器或 3.4 或更早版本的服务器时,现代机制不会重试写入。
以下错误将导致重试写入:
包括超时在内的网络错误
“not master”错误
“节点正在恢复”错误
在重试写入之前,驱动程序将执行服务器选择,因为发送原始写入的服务器可能不再可用。
旧版可重试写入
如果通过设置客户端选项retry_writes: false
或使用retryWrites=false
URI 选项禁用了现代可重试写入机制,则驱动程序将利用传统可重试写入机制。 旧版机制重试写入的操作与现代机制相同。旧版机制默认会像现代机制一样重试一次;要更改重试次数,请设置:max_write_retries
客户端选项。
旧版重试机制和现代重试机制之间的区别在于,旧版机制会针对与现代机制不同的错误集进行重试写入,并且在遇到网络超时时不会重试写入。
禁用可重试写入
要禁用所有写入重试,请设置以下客户端选项: retry_writes: false, max_write_retries: 0
。
日志记录
您可以使用默认的全局驱动程序记录器,也可以设置自己的记录器。 要设置自己的:
Mongo::Logger.logger = other_logger
请参阅 Ruby记录器文档 有关默认记录器API和可用级别的更多信息。
更改记录器级别
要更改记录器级别:
Mongo::Logger.logger.level = Logger::WARN
为了进行更多控制,可以将记录器传递给客户端,以便按客户端控制日志记录。
my_logger = Logger.new(STDOUT) Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :logger => my_logger )
截断
默认日志记录会将日志截断为 250 个字符。 要关闭此功能,请向客户端实例传递一个选项。
Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :truncate_logs => false )
压缩
要使用传输协议压缩,必须使用:compressors
Ruby 选项或compressors
URI 选项显式请求至少一个压缩器。 如果没有显式请求压缩程序,则即使系统上存在一个或多个压缩程序所需的依赖项,驱动程序也不会使用压缩。
驱动程序会选择服务器也支持的所请求压缩程序中的第一个压缩程序。 该驱动程序当前支持zstd
、 snappy
和zlib
压缩器。 建议使用zstd
压缩器,因为与其他压缩器相比,它可以在相同的 CPU 消耗下产生最高的压缩率。 为了最大限度地提高服务器兼容性,可以指定所有三个压缩程序,例如指定为compressors: ["zstd", "snappy", "zlib"]
。
zstd
压缩器需要 zstd-Ruby 要安装的库。snappy
压缩器需要 snappy 要安装的库。如果请求zstd
或snappy
压缩,并且相应的库无法加载,则驱动程序将在Mongo::Client
创建期间引发错误。 zlib
压缩要求存在zlib
标准库扩展。
服务器对各种压缩器的支持情况如下:
zstd
需要,并在 MongoDB 4.2 或更高版本中默认启用。snappy
需要 MongoDB 3.4 或更高版本,并在 MongoDB 3.6 或更高版本中默认启用。zlib
需要 MongoDB 3.6 或更高版本,并在 MongoDB 4.2 和更高版本中默认启用。
服务器 API 参数
从 MongoDB 5.0 开始,应用程序可以请求服务器根据特定的服务器 API 版本运行。
可以通过Client
的:server_api
选项指定服务器 API 参数。 这些参数无法通过 URI 提供。
目前唯一定义的 API 版本是"1"
。 可以通过以下方式请求:
client = Mongo::Client.new(['localhost'], server_api: {version: "1"})
MongoDB Server 将 API 版本定义为字符串值。 为方便起见,如果 API 版本以整数形式提供,Ruby 驱动程序会将其字符串化并作为字符串发送到服务器:
client = Mongo::Client.new(['localhost'], server_api: {version: 1})
请注意,服务器定义的 API 版本可能不是字符串化整数。 应用程序不得假设所有合法 API 版本都可以表示为整数。
当请求特定的 API 版本时,属于该 API 版本的操作将按照该 API 版本中指定的方式运行。 不属于指定 API 版本的操作的行为与根本未指定 API 版本时相同。 其行为受已配置 API 版本约束的操作是指包括命令参数、查询、聚合管道阶段和参数的命令。
应用程序可以通过设置:strict
选项来请求服务器拒绝不属于指定 API 版本的所有操作:
client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true})
例如,由于:tailable
选项不是服务器 API 版本 1 的一部分,因此以下查询将失败:
client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true}) client['collection'].find({}, tailable: true) # => Mongo::Error::OperationFailure (BSON field 'FindCommand.tailable' is not allowed with apiStrict:true. (323) (on localhost:27017, modern retry, attempt 1))
应用程序可以通过设置:deprecation_errors
选项来请求服务器拒绝在指定 API 版本中已弃用的所有操作:
client = Mongo::Client.new(['localhost'], server_api: {version: "1", deprecation_errors: true})
请注意,截至撰写本文时,API 版本"1"
中没有任何已弃用的操作。
如果已在Client
对象上定义服务器 API 参数,则客户端将作为每个[ 1 ]执行操作的一部分发送这些参数。
[1] | getMore 命令和事务中的命令不接受 API 参数,因此驱动程序在这些情况下不会发送这些参数。 |
5.0 之前的 MongoDB Server 无法识别 API 参数,如果应用程序配置这些参数,则会产生各种错误。Ruby 驱动程序会将 API 参数发送到所有 MongoDB 3.6 及更高版本的服务器,但仅当应用程序与 MongoDB 5.0 或更高版本的服务器通信时才应配置 API 参数。 无法将 API 参数发送到使用旧版传输协议的 MongoDB 3.4 及更早版本的服务器;如果应用程序配置了 API 参数并连接到 MongoDB 3.4 或更早版本的服务器,则驱动程序将在每次操作时产生错误。
命令助手允许应用程序向服务器发送手动构建的命令。 如果客户端未配置服务器 API 参数,则可使用命令助手发出带 API 参数的命令:
client.database.command( ping: 1, apiVersion: "1", apiStrict: false, apiDeprecationErrors: false, )
如果客户端配置了服务器 API 参数,则命令助手可能无法用于发出带有服务器 API 参数的命令。 这包括向客户端和命令助手提供的服务器 API 参数相同的情况。 如果客户端是使用服务器 API 参数构建的,要发送不同的 API 参数(或根本不发送参数),必须从头开始或使用with
方法构建新客户端。
服务器 API 参数只能在客户端级别指定。 不得在数据库、collection、会话、事务或单个操作级别上指定它们。
开发配置
驱动程序的默认配置适用于生产部署。在开发过程中,可以对某些设置进行调整,以提供更好的开发体验。
:server_selection_timeout
:如果您的 MongoDB Server 在本地运行,并且您会手动启动它,请将此值设置为较低的值(例如1
)。如果没有服务器正在运行,则较低的服务器选择超时会导致驱动程序快速失败。
生产配置
在生产中使用 Ruby 驱动程序部署应用程序时,请考虑以下因素:
从驱动程序版本 2.11 开始,完全遵循
:min_pool_size
客户端选项 — 驱动程序将与标识为独立运行的主节点或从节点的每台服务器创建相同数量的连接。 在以前的驱动程序版本中,驱动程序按需创建连接。 从驱动程序版本 2.11 开始,使用:min_pool_size
的应用程序会发现与所有服务器的空闲连接数量增加,尤其是与副本集部署中的从节点和分片集群中的节点的空闲连接。如果应用程序由另一台 Web 服务器或负载均衡器进行反向代理,则通常应将
server_selection_timeout
设置为低于反向代理读取超时的值。 例如, Heroku 请求超时 为30 秒且不可配置;如果将使用 MongoDB 的 Ruby 应用程序部署到 Heroku,请考虑将服务器选择超时降低至20 或15 秒。
功能标志
以下是 Mongo Ruby 驱动程序提供的功能标志列表:
标记 | 说明 |
---|---|
broken_view_aggregate | 当此标志关闭时,在视图上完成的聚合将对该视图中包含的文档执行,而不是对collection中的所有文档执行。当此标志打开时,将忽略视图筛选器,并将聚合应用于视图collection中的所有文档。(默认值:true) |
broken_view_options | 关闭此标志后,视图选项将正确传播到 aggregate 、 count 、 count_documents 、 distinct 和estimated_document_count 方法。 当此标志打开时,这些方法中的视图选项将被忽略。 (默认值:true) |
validate_update_replace | 验证替换文档的根目录中没有原子操作符(以 $ 开头的操作符),以及更新文档的根目录中仅存在原子操作符。 如果此功能标志已打开,则将对无效的更新或替换文档引发错误,如果未打开,则会在日志中输出警告。 (默认值:false) |
这些功能标志可以直接在Mongo
模块上设置,也可以使用options
方法设置:
Mongo.validate_update_replace = true Mongo.options = { validate_update_replace: true }