创建客户端
本页内容
- 使用
Mongo::Client
- 块语法
- 数据库选择
- 连接类型
- 独立服务器连接
- 副本集连接
- 分片集群连接
- 直接连接
- 负载均衡器连接
- 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 配置
- 连接池
- 与分叉服务器一起使用
- 手动处理进程分叉
- 故障排除
- 可重试读取
- 现代可重试读取
- 传统可重试读取
- 禁用可重试读取
- 可重试写入
- 现代可重试写入
- 传统可重试写入
- 禁用可重试写入
- 日志记录
- 更改日志记录级别
- 截断
- 压缩
- 服务器 API 参数
- 开发配置
- 生产配置
- 功能标志
使用Mongo::Client
要连接到 MongoDB 部署,创建一个 Mongo::Client
对象。提供主机列表和选项或一个连接字符串 URI 给``Mongo::Client``构造函数。客户端选择的数据库名默认为 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中还有其他特殊数据库,只能用于其声明的目的
连接类型
默认情况下,驱动程序将自动识别它被指示连接到的部署类型(除了负载均衡部署)并以与部署类型相匹配的方式行为。以下小节将描述驱动程序在每种部署类型中的行为以及如何强制特定行为,从而绕过自动部署类型检测。
请注意,部署类型的检测发生在驱动程序收到它被指示连接到的任何服务器首次回复时(除非请求负载均衡模式,见下文)。即使底层部署被不同类型的部署所替换,驱动程序也将保持发现的或配置的拓扑。特别是,当在同一地址用分片集群替换副本集时,客户端实例必须被重新创建(例如通过重启应用程序),以便与分片集群通信。
目前不支持自动检测负载均衡部署。负载均衡部署将被视为其底层类型的部署,这通常是分片集群。当将负载均衡部署视为分片集群时,驱动程序将无法正确运行,因此当部署是负载均衡时,客户端必须显式配置为连接到负载均衡器。
独立服务器连接
如果部署是单个服务器,也称为独立部署,所有操作都将指向指定的服务器。
如果服务器关闭并被副本集节点替换,驱动程序将继续向该节点发送所有操作,即使该节点是或成为次要节点。
要强制独立连接,请参阅下文的直接连接部分。
副本集连接
连接到副本集时,只需要将副本集中的任何节点的地址传递给驱动程序。该节点不必是主节点,它也可以是一个隐藏节点。然后驱动程序将自动发现其余节点。
然而,建议指定所有属于副本集的节点,以便在某个或多个节点不可用的情况下(例如,由于维护或重新配置),驱动程序仍可以连接到副本集。
副本集连接示例
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集群,请连接到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说明。
直接连接
要禁用部署类型发现并强制所有操作都在特定服务器上执行,请指定 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
路由器,反之亦然)。
负载均衡器连接
与其他部署类型不同,当前驱动程序无法自动检测负载均衡器部署。
要连接到负载均衡器,请指定 Ruby 选项 load_balanced: true
或 URI 选项 loadBalanced=true
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")
使用这些选项时,如果指定的服务器不是负载均衡器,客户端将失败所有操作(直到服务器成为负载均衡器)。
即使服务器没有将其识别为负载均衡器,也将其视为负载均衡器,请使用 Ruby 选项 connect: :load_balanced
或 URI 选项 connect=load_balanced
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
实例。
您可以将 稳定 API 版本设置为客户端选项,以避免在升级到新服务器版本时出现破坏性更改。
以下代码展示了如何在连接到 MongoDB 部署时指定连接字符串和稳定 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 查找中单独检索的,在网络连接不可靠的环境中,当 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 日志中的应用程序名称。 | 字符串 | 无 | ||||||
:auth_mech | 指定要使用的认证机制。可以是以下之一: :gssapi 、:mongodb_cr 、:mongodb_x509 、:plain 、:scram 、:scram256 。GSSAPI(Kerberos)认证需要额外的依赖项。[链接](/docs/ruby-driver/current/reference/authentication/#std-label-kerberos) | 符号 | 如果没有提供用户凭证,则为 nil 。如果提供了用户凭证,则默认值取决于服务器版本。MongoDB 4.0 及更高版本:如果用户凭证对应支持 SCRAM-SHA-256 认证的用
| ||||||
:auth_mech_properties | 提供额外的认证机制属性。 属性中的键不区分大小写。客户端创建时,键将被转换为小写。 | 哈希 | 使用 GSSAPI 认证机制时,默认属性为 {service_name: "mongodb"} 。否则默认为 nil。 | ||||||
:auth_source | 指定认证源。 | 字符串 | 对于 MongoDB 2.6 及更高版本:如果提供了凭证,则为 admin,否则为当前数据库。 | ||||||
:auto_encryption_options | 自动加密配置的选项的
有关这些选项的格式化信息,请参阅客户端加密教程中的“自动加密选项”部分。 | 哈希 | 无 | ||||||
:bg_error_backtrace | 实验性。控制当后台线程出现错误时,是否以及如何记录回溯信息。如果设置为 true ,则驱动程序将记录完整的回溯信息。如果设置为正整数,则驱动程序将记录多达那么多行的回溯信息。如果设置为 false 或 nil ,则不会记录回溯信息。其他值视为错误。 | true ,false ,nil ,Integer | 无 | ||||||
:compressors | 按优先顺序列出要使用的潜在压缩器。请参阅以下内容以了解驱动程序如何实现压缩。 | Array<String> | 无 | ||||||
:connect | 已弃用。 禁用通常由驱动程序执行的部署拓扑发现,并将集群拓扑强制设置为特定类型。有效值有 :direct ,:load_balanced ,:replica_set 或 :sharded 。如果使用 :load_balanced ,则客户端将表现得好像连接到了负载均衡器,无论它连接到的服务器是否声明自己为负载均衡器。 | 符号 | 无 | ||||||
:connect_timeout | 在抛出异常之前等待建立套接字连接的秒数。此超时也用于 SRV DNS 记录解析。 nil 和 0 表示无超时。如果传递了无效的超时值(例如负值或非数值),则客户端创建将失败并产生错误。 | Float | 10 | ||||||
:database | 要连接的数据库的名称。 | 字符串 | admin | ||||||
: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 | 在连接池关闭连接之前,连接可以空闲的最大时间(以秒为单位)。 警告:当连接到负载均衡器时,驱动程序使用现有连接来迭代游标(包括更改流)和执行事务。通过此选项设置空闲时间可能会导致驱动程序关闭后续操作所需的连接,导致这些操作失败。 | Integer | 无 | ||||||
:max_pool_size | 每个服务器的连接池的最大大小。将此选项设置为 0 将从连接池中移除最大大小限制,允许其增长到任意数量的连接。 | Integer | 20 | ||||||
:max_read_retries | 当使用传统读取重试时,最大读取重试次数。设置为 0 以禁用传统读取重试。 | Integer | 1 | ||||||
:max_write_retries | 当使用传统写入重试时,最大写入重试次数。设置为 0 以禁用传统写入重试。 | Integer | 1 | ||||||
:min_pool_size | 每个服务器的连接池中的最小连接数。驱动程序将在后台建立连接,直到池中包含这么多连接。 | Integer | 0 | ||||||
:monitoring | 监控对象。 | Object | 无 | ||||||
:password | 用于认证的用户密码。 | 字符串 | 无 | ||||||
:platform | 在服务器版本 >= 3.4 时,将包含在连接服务器到 mongod 日志中打印的元数据中的平台信息。 | 字符串 | 无 | ||||||
:read | 指定作为哈希选择的读取优先级模式和标签集。在哈希中允许的键有
如果提供了标签集,它们必须是一个哈希数组。如果服务器的标签与提供的标签集中的任何一个哈希匹配,则该服务器满足读取优先级。 每个标签集必须是一个哈希,在使用它进行服务器选择之前,将内部转换为 | 哈希 | { :mode => :primary } | ||||||
:read_concern | 指定读取关注选项。唯一有效的键是 level ,其有效值是 :local 、:available 、:majority 、:snapshot 和 :linearizable 。 | 哈希 | 无 | ||||||
:read_retry_interval | 在 mongos 上读取重试的时间间隔(以秒为单位)。 | Integer | 5 | ||||||
:replica_set | 当连接到副本集时,这是根据服务器进行过滤的集的名称。 | 字符串 | 无 | ||||||
:retry_writes | 如果单个语句的写操作由于网络错误而失败,当连接到服务器版本 3.6+ 时,驱动程序会自动重试一次。 | Boolean | true | ||||||
:sdam_proc | 由于客户端在构造时立即开始后台监控部署,因此构造客户端并在单独的语句中订阅 SDAM 事件可能会导致订阅者未接收到某些 SDAM 事件。`:sdam_proc` 选项允许在发布任何 SDAM 事件之前向正在构建的客户端添加事件订阅者。 传递一个 注意:在`:sdam_proc` 调用提供的 | Proc | 无 | ||||||
:server_api | 请求的服务器 API 版本。这是一个包含以下允许项的哈希:- 注意,服务器 API 版本只能作为 Ruby 选项指定,而不是作为 URI 选项,并且不能覆盖数据库和集合对象。 如果客户端更改了服务器 API 版本(例如通过 | 哈希 | 无 | ||||||
:server_selection_timeout | 在引发异常之前,等待选择合适的服务器执行操作所需秒数。 | Float | 30 | ||||||
:socket_timeout | 在套接字上执行操作之前等待秒数,如果超出则引发异常。`nil` 和 `0` 表示没有超时。如果传递无效的超时值(如负值或非数值),客户端创建将失败并出现错误。 | Float | 无 | ||||||
:srv_max_hosts | 驱动程序将与分片拓扑通信的 mongoses 的最大数量。如果此选项设置为 0,则没有最大数量限制。如果给定的 URI 解析出的主机数超过 ` :srv_max_hosts `,则客户端将随机选择一个大小为 `:srv_max_hosts ` 的主机子集。请注意,在客户端构造过程中被驱动程序忽略的主机永远不会被使用。如果驱动程序选择的主机不可用,则客户端将完全停止工作,即使部署中还有其他可用的 mongoses。 | Integer | 0 | ||||||
:srv_service_name | 在 SRV DNS 查询中使用的服务名称。 | 字符串 | mongodb | ||||||
:ssl | 告诉客户端通过 TLS 连接到服务器。 | Boolean | false | ||||||
:ssl_ca_cert | 包含用于验证连接另一端传递的证书的证书授权证书的文件路径。对于 ` :ssl_verify `,必须提供 `:ssl_ca_cert `、`:ssl_ca_cert_string ` 或 `:ssl_ca_cert_object ` 中的一个(按优先级顺序)。 | 字符串 | 无 | ||||||
: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 ` 中的一个(按优先级顺序)。 | 字符串 | 无 | ||||||
:ssl_cert | 客户端证书文件的路径,用于向 MongoDB 服务器标识应用程序。该文件还可以包含证书的私钥;如果包含,则此选项将忽略私钥。文件还可以包含形成从客户端证书到 CA 证书的证书链的中间证书;任何中间证书都将由驱动程序解析,并作为 ` 如果存在此选项,则优先于 ` | 字符串 | 无 | ||||||
:ssl_cert_object | 用于向 MongoDB 服务器标识应用程序的 OpenSSL::X509::Certificate。只能通过此选项传递一个证书。 | OpenSSL::X509::Certificate | 无 | ||||||
:ssl_cert_string | 包含用于识别应用程序到MongoDB服务器的PEM编码证书的字符串。该字符串可能还包含证书的私钥;如果是这样,私钥将被此选项忽略。该字符串还可能包含构成从客户端证书到CA证书的证书链的中间证书;任何中间证书都将由驱动程序解析,并通过 如果存在此选项,则它将覆盖 | 字符串 | 无 | ||||||
:ssl_key | 用于识别与MongoDB连接的私钥文件。请注意,即使密钥存储在与证书相同的文件中,也需要明确指定两者。如果存在此选项,则它将覆盖:ssl_key_string 和 :ssl_key_object 的值。 | 字符串 | 无 | ||||||
:ssl_key_object | 用于识别与MongoDB连接的私钥。 | OpenSSL::PKey | 无 | ||||||
:ssl_key_pass_phrase | 私钥的密码。 | 字符串 | 无 | ||||||
:ssl_key_string | 包含用于识别与MongoDB连接的PEM编码私钥的字符串。如果存在此参数,则它将覆盖:ssl_key_object 的值。 | 字符串 | 无 | ||||||
: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端点相匹配。此设置将覆盖:ssl_verify,以确定是否执行OCSP端点验证。 | Boolean | true | ||||||
:truncate_logs | 是否在默认的250个字符处截断日志。 | Boolean | true | ||||||
:user | 用于身份验证的用户名。 | 字符串 | 无 | ||||||
:wait_queue_timeout | 等待连接池中的连接变为可用的秒数。 | Float | 10 | ||||||
:wrapping_libraries | 关于包装驱动程序的库(如ODMs)的信息。首先指定较低级别的库。允许的散列键::name, :version, :platform。例如: [name: 'Mongoid', version: '7.1.2'] | Array | 无 | ||||||
:write | 已弃用。相当于:write_concern 选项。如果同时指定:write 和:write_concern,则它们的值必须相同。 | 哈希 | { w: 1 } | ||||||
:write_concern | 指定写关注选项为
| 哈希 | { w: 1 } | ||||||
:zlib_compression_level | 如果使用压缩,指定要使用的Zlib压缩级别。有关有效级别,请参阅Ruby的Zlib模块。 | Integer | 无 |
注意
Ruby驱动程序不实现证书吊销列表(CRL)检查。
URI选项
由于URI选项必须使用驼峰命名法,这不是Ruby的标准,以下表格显示了URI选项及其对应的Ruby选项。
URI选项的详细信息请参阅连接URI参考。
注意
URI中设置为毫秒的选项在Ruby中表示为浮点数
,单位是秒。
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选项不同,该选项在无效值(例如负值和非数值)上失败客户端创建,通过此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=整数 | :max_pool_size => 整数 |
minPoolSize=整数 | :min_pool_size => 整数 |
readConcernLevel=字符串 | :read_concern => 字典 |
readPreference=字符串 | { :read => { :mode => 符号 }} |
readPreferenceTags=字符串数组 |
readPreferenceTags字段的每个实例都是一个逗号分隔的键:值对,它们将按照指定的顺序出现在:tag_sets数组中。例如, |
replicaSet=字符串 | :replica_set => 字符串 |
retryWrites=布尔值 | :retry_writes => 布尔值 |
serverSelectionTimeoutMS=整数 | :server_selection_timeout => 浮点数 |
socketTimeoutMS=整数 |
与对应的Ruby选项不同,该选项在无效值(例如负值和非数值)上失败客户端创建,通过此URI选项提供的无效值将被忽略并显示警告。 |
srvMaxHosts=整数 | :srv_max_hosts => 整数 |
srvServiceName=字符串 | :srv_service_name => 字符串 |
ssl=布尔值 | :ssl => true|false |
tls=布尔值 | :ssl => 布尔值 |
tlsAllowInvalidCertificates=布尔值 |
因为 |
tlsAllowInvalidHostnames=布尔值 |
因为 |
tlsCAFile=字符串 | :ssl_ca_cert => 字符串 |
tlsCertificateKeyFile=字符串 | :ssl_cert => 字符串 |
tlsCertificateKeyFile=字符串 | :ssl_key => 字符串 |
tlsCertificateKeyFilePassword=字符串 | :ssl_key_pass_phrase => 字符串 |
tlsDisableOCSPEndpointCheck=布尔值 |
因为 |
tlsInsecure=布尔值 |
因为tlsInsecure使用 |
w=整数|字符串 | { :write_concern => { :w => 整数|字符串 }} |
waitQueueTimeoutMS=整数 | :wait_queue_timeout => 浮点数 |
wtimeoutMS=整数 | { :write_concern => { :wtimeout => 整数 }} |
zlibCompressionLevel=整数 | :zlib_compression_level => 整数 |
注意
Ruby驱动程序仅在接收到明确签名的响应,表明服务器的证书已被吊销时才失败连接。因此,驱动程序不识别 tlsDisableCertificateRevocationCheck
URI 选项。如果此选项在 URI 中提供,则将被忽略。
超时选项
server_selection_timeout
执行操作时,等待驱动程序找到合适的服务器发送操作的秒数。默认为30。
0的值表示没有超时。
当通过URI选项传递无效值(例如,负值或非数值)时,将忽略无效输入并发出警告。当直接通过Ruby选项将无效值传递给客户端时,客户端构造将失败并出现错误。
在副本集部署中,此超时应该设置得超过典型的 副本集选举时间,以便驱动程序可以透明地处理主节点更改。此超时还允许应用程序和数据库同时启动;应用程序将等待这么多时间以等待数据库可用。
如果应用程序服务器位于反向代理后面,服务器选择超时应该低于反向代理上配置的请求超时(例如,这适用于在Heroku上部署的情况,其路由层有固定的30秒超时)。在开发中,此值可以降低以在服务器未运行时提供更快的失败。
socket_timeout
等待套接字读取或写入操作在常规(非监控)连接上完成的秒数。默认为无超时。
0的值表示没有超时。
当通过URI选项传递无效值(例如,负值或非数值)时,将忽略无效输入并发出警告。当直接通过Ruby选项将无效值传递给客户端时,客户端构造将失败并出现错误。
此超时应考虑网络延迟和操作持续时间。例如,将此超时设置为5秒将在服务器上执行超过5秒的查询时引发Mongo::Error::SocketTimeoutError
。
请注意,尽管默认情况下未设置套接字超时,但操作系统可能会根据其配置超时读取操作。保持活动状态设置旨在检测损坏的网络连接(而不是简单地因为操作执行时间过长而终止操作)。
请注意,如果由于驱动程序超时socket_timeout
值而导致操作超时,则不会在服务器上终止。因此,建议对于可能运行时间较长的操作使用max_time_ms
选项,因为这将在服务器上终止它们的执行。
此选项不适用于监控连接。
connect_timeout
等待套接字连接到服务器建立的秒数。默认为10。
此超时也用作监控连接的连接超时和套接字超时。
当使用mongodb+srv://
URI时,此超时也用于SRV和TXT DNS查找。请注意,超时适用于每个查找;由于DNS后缀搜索列表,可能需要在单个名称解析过程中执行多个查找。
wait_queue_timeout
等待连接池中的连接可用的秒数。默认为10。
从驱动程序版本2.11开始,此超时值应至少与connect_timeout
一样大,因为连接池现在在返回之前会完全建立连接,这可能需要几次网络往返。
max_time_ms
在特定操作上指定为选项,指定服务器上允许操作执行的毫秒数。默认不设置。
考虑使用此选项而不是socket_timeout
,以便在操作执行时间过长时在服务器上中断潜在的长时间运行的操作。
wtimeout
等待写入被写入关注中指定数量的服务器确认的毫秒数。默认不设置,指示服务器使用其默认值。此选项可以在客户端全局设置,或者在: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服务器会尝试验证连接客户端的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上下文钩子”的方法——这些是由用户提供的,在任意TLS套接字连接之前会被调用的Proc
,可以用来修改套接字使用的底层OpenSSL::SSL::SSLContext
对象。
要设置TLS上下文钩子,请将Proc
添加到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
将在每个Mongo::Socket::SSL
对象创建过程中按顺序执行。
可以通过调用Mongo.tls_context_hooks=
来分配整个钩子数组,但这样做将会移除之前分配的钩子。建议使用Array#push
或Array#unshift
方法来添加新的钩子。
也可以通过在应用程序的其它地方存储对Proc的引用,然后使用Array#delete_if
来从Mongo.tls_context_hooks
中移除钩子。
警告
TLS上下文钩子是全局的,将会影响每个Mongo::Client
实例。任何允许应用程序启用这些钩子的库应该公开修改钩子的方法(这些方法可以被应用程序调用),而不是在库加载时自动启用钩子。
有关配置MongoDB服务器以使用TLS的更多信息,请参阅MongoDB手册。
使用中间证书
对于客户端和服务器证书,都可以使用证书链。当使用链时,证书颁发机构参数应配置为只包含受信任的根证书;如果有的话,中间证书应分别通过连接到叶服务器和客户端证书之后提供。
:ssl_cert
和:ssl_cert_string
Ruby选项,以及tlsCertificateKeyFile
URI选项,支持证书链。:ssl_cert_object
Ruby选项,它接受一个OpenSSL::X509::Certificate
实例,不支持证书链。
Ruby驱动程序执行严格的X.509证书验证,这要求中间证书(如果有的话)中的以下字段都应设置:
X509v3基本约束:CA:TRUE — 可以签名证书
X509v3密钥使用:Key Cert Sign — 可以签名证书
关于这些标志的更多信息可以在以下Stack Overflow问题中找到:这个Stack Overflow问题。
将中间证书连接到通过 tlsCAFile
/ ssl_ca_cert
选项传入的根CA证书是一种常见的陷阱。这样做会将中间证书提升到可信状态,但它们本身并未与实际的CA根进行验证。有关此问题的更多信息可在这篇邮件列表帖子中找到。
指定CA证书
默认情况下,驱动程序将尝试验证服务器的TLS证书,如果验证失败,将终止连接。默认情况下,驱动程序将使用默认系统根证书存储作为信任锚。要指定服务器证书所签名的CA证书,请使用
以下Ruby选项:
:ssl_ca_cert
/:ssl_ca_cert_string
/:ssl_ca_cert_object
URI选项
tlsCAFile
。
如果提供了这些选项之一,服务器证书将仅与指定的CA证书进行验证,而不会使用默认的系统根证书存储。
如果不进行服务器TLS证书验证(不推荐),请指定Ruby选项ssl_verify: false
或URI选项tlsInsecure=true
。
指定多个CA证书
Ruby选项:ssl_ca_cert
和URI选项tlsCAFile
可以用于包含多个证书的文件。所有引用的证书都将成为信任锚点。
:ssl_ca_cert_object
选项接受证书数组,因此也可以用于将多个证书添加为证书颁发机构。
:ssl_ca_cert_string
选项仅支持指定一个CA证书。
警告
中间证书不得在CA证书选项指定的文件中提供。这样做会将中间证书提升为根证书的地位,而不是将中间证书与根证书进行验证。
如果需要使用中间证书,请将它们指定为客户端或服务器TLS证书文件的一部分。
OCSP验证
如果服务器提供的证书包含OCSP端点URI,则驱动程序将向指定的端点发出OCSP请求以验证证书的有效性。
可以通过将Ruby选项:ssl_verify_ocsp_endpoint
设置为false
或通过在创建客户端时设置URI选项tlsDisableOCSPEndpointCheck
为true
来禁用OCSP端点检查。
注意
由于JRuby没有正确公开OCSP端点URI,因此目前在JRuby上运行时不会执行OCSP端点检查。
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 参数,系统配置将生效。
要使用较小的值,或者更改不公开所需API的环境(如JRuby)中的参数,请按照以下方式在系统级别调整参数:MongoDB诊断FAQ中的keepalive部分。
连接池
Mongo::Client
实例为每个客户端连接的服务器有一个连接池。该池在需要时创建连接以支持由应用程序发出的并发MongoDB操作。连接没有线程亲和性。
客户端实例为每个已知服务器额外打开一个连接以监控服务器状态。
每个连接池的大小限制为max_pool_size
,默认为5。当应用程序中的线程开始对MongoDB进行操作时,它会尝试从池中检索一个连接来发送该操作。如果池中有些连接可用,它将从池中借出一个连接并用于该操作。如果没有可用的连接,并且池的大小小于max_pool_size
,将创建一个新的连接。如果所有连接都在使用中,并且池已达到最大大小,线程将等待另一个线程将连接返回到池中。如果将max_pool_size
设置为0,则池中最大连接数没有限制。
每个连接池对可以同时连接到服务器的连接数有限制。这个限制被称为 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个监控连接)。如果应用程序使用读取偏好查询辅助节点,它们的池也会增长,总连接数可以达到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),如果您在分叉后不在子进程中重新启动驱动程序的监控线程,尽管您的子进程最初可能看起来可以正常工作,但您最终会看到 Mongo::Error::NoServerAvailable
异常,如果/当您的 MongoDB 集群状态改变时,例如由于网络错误或维护事件。
关于(2),如果一个子进程重用了父进程的文件描述符,您将看到带有类似 Errno::EPIPE: 管道已损坏
和 EOFError: 文件末尾已到达
等消息的 Mongo::Error::SocketError
错误。
当 Ruby 驱动程序在 Web 应用程序中使用时,如果可能,我们建议不要在父进程中创建任何 Mongo::Client
实例(在工作者被分叉之前),而是在工作者中仅创建客户端实例。
手动处理进程分叉
某些高级用例,例如 Puma的fork_worker选项,需要父进程和子进程中都打开Mongo::Client实例。在这种情况下,您必须手动处理客户端重连。
为此,在fork之前,立即关闭父进程中的任何现有客户端连接。这将防止父进程因子进程复用父进程的文件描述符而出现网络和监控错误。
# Immediately before fork client.close
注意
调用Client#close
不会中断正在进行的数据库操作。当您执行新操作时,客户端将自动重连。
然后,在fork之后立即,在新生成的子进程中重新连接客户端,这将重新启动驱动程序的监控线程。
# Immediately after fork client.reconnect
大多数Web服务器提供钩子,供应用程序在工作进程fork时执行操作。推荐使用的钩子是
对于Puma,使用
before_fork
和on_refork
在父进程中关闭客户端,使用on_worker_boot
在子进程中重连。对于Unicorn,使用
before_fork
在父进程中关闭客户端,并使用after_fork
在子进程中重新连接客户端。对于Passenger,使用
starting_worker_process
在子进程中重新连接客户端(Passenger似乎没有预分叉钩子)。
有关更多示例,请参阅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
或使用 URI 选项 retryReads=false
明确请求传统可重试读取。
传统可重试读取
通过设置客户端选项 retry_reads: false
或将 retryReads=false
URI 选项传递给客户端,可以使用 Ruby 驱动的传统读取重试行为。
在使用传统读取重试行为时,可以通过指定客户端选项 max_read_retries
来设置重试次数。当使用 2.9.0 或更高版本的驱动程序时,将使用传统重试读取进行重试的操作集合与上述现代重试读取描述的操作集合相同。在较旧版本的驱动程序中,传统重试写入的行为不同,其中某些操作不会被重试。
截至驱动程序版本 2.9.0,传统的读取重试在重试操作之前会进行服务器选择,类似于现代可重试写入。
禁用可重试读取
要禁用所有读取重试,请设置以下客户端选项:retry_reads: false, max_read_retries: 0
。
可重试写入
驱动程序实现了两种写入重试机制:现代和传统。截至驱动程序版本 2.9.0,对支持的服务器默认使用现代机制,而传统机制已弃用并在所有服务器版本中默认禁用。
以下在集合的日常操作中使用的写入方法会受到写入重试的影响:
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或更高版本的副本集或分片集群时重试失败的写操作,因为这些操作需要在服务器上使用操作日志。当驱动程序连接到独立MongoDB服务器或服务器版本为3.4或更旧版本时,现代机制不会重试写操作。
以下错误将导致写操作重试
网络错误,包括超时
"not master"错误
"node is recovering"错误
在重试写操作之前,驱动程序将执行服务器选择,因为原始写操作发送到的服务器可能已经不再可用。
旧版可重试写操作
如果通过设置客户端选项retry_writes: false
或使用retryWrites=false
URI选项禁用现代可重试写操作机制,则驱动程序将使用旧版可重试写操作机制。旧版机制与新版机制在相同的操作上重试写操作。默认情况下,旧版机制重试一次,就像新版机制一样;要更改重试次数,请设置:max_write_retries
客户端选项。
旧版和现代重试机制之间的区别在于,与新版机制相比,旧版机制在遇到不同的错误集上重试写操作,并且特别不会在遇到网络超时时重试写操作。
禁用可重试的写入
要禁用所有写入重试,请设置以下客户端选项:retry_writes: false, max_write_retries: 0
。
日志记录
您可以使用默认的全局驱动程序日志记录器或设置自己的。要设置自己的
Mongo::Logger.logger = other_logger
请参阅Ruby Logger 文档以获取有关默认日志记录器 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 )
压缩
要使用线协议压缩,必须明确请求至少一个压缩器,使用Ruby选项中的:compressors
或URI选项中的compressors
。如果没有明确请求压缩器,即使系统上存在一个或多个压缩器的必需依赖项,驱动程序也不会使用压缩。
驱动程序选择请求的压缩器列表中第一个同时由服务器支持的压缩器。驱动程序目前支持zstd
、snappy
和zlib
压缩器。《code class="leafygreen-ui-1l06pbn">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 版本运行。
可以通过 :server_api
选项将服务器 API 参数指定给 Client
。这些参数不能通过 URI 提供。
当前定义的唯一API版本是"1"
。可以按照以下方式请求
client = Mongo::Client.new(['localhost'], server_api: {version: "1"})
MongoDB服务器将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"
中没有弃用的操作。
如果服务器API参数已在Client
对象上定义,它们将被客户端作为每个[1]执行的操作的一部分发送。
[1] | getMore 命令和事务中的命令不接受API参数,因此在这些情况下驱动程序不会发送它们。 |
5.0之前的MongoDB服务器不识别API参数,如果应用程序配置了它们,将产生各种错误。Ruby驱动程序将向所有MongoDB 3.6及更高版本的服务器发送API参数,但只有在应用程序与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参数只能在客户端级别指定。它们不能在数据库、集合、会话、事务或单个操作级别指定。
开发配置
驱动程序的默认配置适用于生产部署。在开发过程中,可以调整一些设置以提供更好的开发者体验。
:server_selection_timeout
:如果您的MongoDB服务器在本地运行且您手动启动它,请将此设置为较低值(例如,1
)。较短的连接超时会导致服务器未运行时驱动程序快速失败。
生产配置
在生产环境中使用Ruby驱动程序部署应用程序时,请考虑以下几点:
从驱动程序版本2.11开始,客户端选项
:min_pool_size
被完全尊重 - 驱动程序将为每个标识为独立、主或次服务器的服务器创建这么多连接。在之前的驱动程序版本中,驱动程序按需创建连接。使用:min_pool_size
的应用程序将在驱动程序版本2.11及更高版本中看到所有服务器上的空闲连接数量增加,尤其是在副本集部署中的次级和分片集群中的节点。如果应用程序由另一个Web服务器或负载均衡器反向代理,则通常应将
server_selection_timeout
设置为比反向代理的读取超时更低的值。例如,Heroku请求超时 为30秒且不可配置;如果使用MongoDB在Heroku上部署Ruby应用程序,请考虑将服务器选择超时降低到20或15秒。
功能标志
以下是由Mongo Ruby Driver提供的功能标志列表
标志 | 描述 |
---|---|
broken_view_aggregate | 当此标志关闭时,对视图执行的聚合将在该视图包含的文档上执行,而不是在集合中所有文档上执行。当此标志开启时,视图过滤器将被忽略,聚合将应用于视图集合中的所有文档。(默认: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 }