配置
在此页面上
Mongoid 通常通过指定选项和客户端的 mongoid.yml
文件进行配置。最简单的配置如下:将 Mongoid 配置为与位于“localhost:27017”的 MongoDB Server 通信并使用名为“mongoid”的数据库。
development: clients: default: database: mongoid hosts: - localhost:27017
配置文件中的顶级密钥(上例中的 development
)指的是应用程序的执行环境名称,即 development
、test
或 production
。以上示例的第三级密钥 default
指的是 Mongo 客户端名称。大多数应用程序将使用名为 default
的单一客户端。
生成默认配置
如果您使用的是 Ruby on Rails,则可以通过运行以下命令让 Mongoid 为您生成默认配置文件:
rails g mongoid:config
配置文件将放在config/mongoid.yml
中。 还将创建一个初始值设定项并将其放在config/initializers/mongoid.rb
中。 建议在config/mongoid.yml
中指定所有配置,但如果您愿意,也可以使用mongoid.rb
初始化程序来设置配置选项。 但请注意, mongoid.yml
中的设置始终优先于初始化程序中的设置。
如果您使用的不是 Ruby on Rails,则可以复制上面给出的最低配置,并将其另存为 config/mongoid.yml
。
加载 Mongoid 配置
如果正在使用 Ruby on Rails,则在加载应用程序时,系统会自动加载存储在 Rails.env
中的当前环境的 Mongoid 配置。
您可能需要通过将以下内容添加到 application.rb
,来将应用程序的 ORM 配置为 Mongoid:
config.generators do |g| g.orm :mongoid end
如果您使用的不是 Ruby on Rails,则必须手动加载 Mongoid 配置。此操作可通过 Mongoid.load!
方法来完成,该方法会将配置文件路径作为参数,如下所示:
# Use automatically detected environment name Mongoid.load!("path/to/your/mongoid.yml") # Specify environment name manually Mongoid.load!("path/to/your/mongoid.yml", :production)
如果要求 Mongoid 自动检测环境名称,它会为此按顺序检查以下来源:
如果定义了
Rails
顶级常量,则检查Rails.env
。如果定义了
Sinatra
顶级常量,则检查Sinatra::Base.environment
。RACK_ENV
环境变量。MONGOID_ENV
环境变量。
还可以直接在 Ruby 中配置 Mongoid,而无需使用配置文件。这种配置方式不支持环境的概念(无论提供什么配置,它都会应用于当前环境)但它确实支持定义多个客户端。
Mongoid.configure do |config| config.clients.default = { hosts: ['localhost:27017'], database: 'my_db', } config.log_level = :warn end
注意
在使用或引用 Mongoid 的任何组件之前,必须先对 Mongoid 进行配置。如果在使用或引用组件后更改配置,则更改可能不会应用于已实例化的组件。
Mongoid 配置选项
以下带注释的示例 mongoid.yml
演示了如何配置 Mongoid。
Mongoid 将客户端配置委托给 Ruby 驱动程序。 请查看驱动程序文档以了解有关驱动程序选项的详细信息。
development: # Configure available database clients. (required) clients: # Defines the default client. (required) default: # Mongoid can connect to a URI accepted by the driver: # uri: mongodb://user:password@mongodb.domain.com:27017/my_db_development # Otherwise define the parameters separately. # This defines the name of the default database that Mongoid can connect to. # (required). database: my_db_development # Provides the hosts the default client can connect to. Must be an array # of host:port pairs. (required) hosts: - localhost:27017 options: # Note that all options listed below are Ruby driver client options (the mongo gem). # Please refer to the driver documentation of the version of the mongo gem you are using # for the most up-to-date list of options. # Change the default write concern. (default = { w: 1 }) # write: # w: 1 # Change the default read preference. Valid options for mode are: :secondary, # :secondary_preferred, :primary, :primary_preferred, :nearest # (default: primary) # read: # mode: :secondary_preferred # tag_sets: # - use: web # The name of the user for authentication. # user: 'user' # The password of the user for authentication. # password: 'password' # The user's database roles. # roles: # - 'dbOwner' # Change the default authentication mechanism. Valid options include: # :scram, :scram256, :mongodb_cr, :mongodb_x509, :gssapi, :aws, :plain. # MongoDB Server defaults to :scram, which will use "SCRAM-SHA-256" if available, # otherwise fallback to "SCRAM-SHA-1" (:scram256 will always use "SCRAM-SHA-256".) # This setting is handled by the MongoDB Ruby Driver. Please refer to: # https://mongodb.com/zh-cn/docs/ruby-driver/current/reference/authentication/ # auth_mech: :scram # The database or source to authenticate the user against. # (default: the database specified above or admin) # auth_source: admin # Force a the driver cluster to behave in a certain manner instead of auto- # discovering. Can be one of: :direct, :replica_set, :sharded. Set to :direct # when connecting to hidden members of a replica set. # connect: :direct # Changes the default time in seconds the server monitors refresh their status # via hello commands. (default: 10) # heartbeat_frequency: 10 # The time in seconds for selecting servers for a near read preference. (default: 0.015) # local_threshold: 0.015 # The timeout in seconds for selecting a server for an operation. (default: 30) # server_selection_timeout: 30 # The maximum number of connections in the connection pool. (default: 5) # max_pool_size: 5 # The minimum number of connections in the connection pool. (default: 1) # min_pool_size: 1 # The time to wait, in seconds, in the connection pool for a connection # to be checked in before timing out. (default: 5) # wait_queue_timeout: 5 # The time to wait to establish a connection before timing out, in seconds. # (default: 10) # connect_timeout: 10 # How long to wait for a response for each operation sent to the # server. This timeout should be set to a value larger than the # processing time for the longest operation that will be executed # by the application. Note that this is a client-side timeout; # the server may continue executing an operation after the client # aborts it with the SocketTimeout exception. # (default: nil, meaning no timeout) # socket_timeout: 5 # The name of the replica set to connect to. Servers provided as seeds that do # not belong to this replica set will be ignored. # replica_set: name # Compressors to use for wire protocol compression. (default is to not use compression) # "zstd" requires zstd-ruby gem. "snappy" requires snappy gem. # Refer to: https://www.mongodb.com/zh-cn/docs/ruby-driver/current/reference/create-client/#compression # compressors: ["zstd", "snappy", "zlib"] # Whether to connect to the servers via ssl. (default: false) # ssl: true # The certificate file used to identify the connection against MongoDB. # ssl_cert: /path/to/my.cert # The private keyfile used to identify the connection against MongoDB. # Note that even if the key is stored in the same file as the certificate, # both need to be explicitly specified. # ssl_key: /path/to/my.key # A passphrase for the private key. # ssl_key_pass_phrase: password # Whether to do peer certification validation. (default: true) # ssl_verify: true # The file containing concatenated certificate authority certificates # used to validate certs passed from the other end of the connection. # ssl_ca_cert: /path/to/ca.cert # Whether to truncate long log lines. (default: true) # truncate_logs: true # Configure Mongoid-specific options. (optional) options: # Allow BSON::Decimal128 to be parsed and returned directly in # field values. When BSON 5 is present and the this option is set to false # (the default), BSON::Decimal128 values in the database will be returned # as BigDecimal. # # @note this option only has effect when BSON 5+ is present. Otherwise, # the setting is ignored. # allow_bson5_decimal128: false # Application name that is printed to the MongoDB logs upon establishing # a connection. Note that the name cannot exceed 128 bytes in length. # It is also used as the database name if the database name is not # explicitly defined. (default: nil) # app_name: nil # When this flag is false, callbacks for embedded documents will not be # called. This is the default in 9.0. # # Setting this flag to true restores the pre-9.0 behavior, where callbacks # for embedded documents are called. This may lead to stack overflow errors # if there are more than cicrca 1000 embedded documents in the root # document's dependencies graph. # See https://jira.mongodb.org/browse/MONGOID-5658 for more details. # around_callbacks_for_embeds: false # Sets the async_query_executor for the application. By default the thread pool executor # is set to `:immediate`. Options are: # # - :immediate - Initializes a single +Concurrent::ImmediateExecutor+ # - :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+ # that uses the +async_query_concurrency+ for the +max_threads+ value. # async_query_executor: :immediate # Mark belongs_to associations as required by default, so that saving a # model with a missing belongs_to association will trigger a validation # error. # belongs_to_required_by_default: true # Set the global discriminator key. # discriminator_key: "_type" # Raise an exception when a field is redefined. # duplicate_fields_exception: false # Defines how many asynchronous queries can be executed concurrently. # This option should be set only if `async_query_executor` is set # to `:global_thread_pool`. # global_executor_concurrency: nil # When this flag is true, any attempt to change the _id of a persisted # document will raise an exception (`Errors::ImmutableAttribute`). # This is the default in 9.0. Setting this flag to false restores the # pre-9.0 behavior, where changing the _id of a persisted # document might be ignored, or it might work, depending on the situation. # immutable_ids: true # Include the root model name in json serialization. # include_root_in_json: false # # Include the _type field in serialization. # include_type_for_serialization: false # Whether to join nested persistence contexts for atomic operations # to parent contexts by default. # join_contexts: false # When this flag is false (the default as of Mongoid 9.0), a document that # is created or loaded will remember the storage options that were active # when it was loaded, and will use those same options by default when # saving or reloading itself. # # When this flag is true you'll get pre-9.0 behavior, where a document will # not remember the storage options from when it was loaded/created, and # subsequent updates will need to explicitly set up those options each time. # # For example: # # record = Model.with(collection: 'other_collection') { Model.first } # # This will try to load the first document from 'other_collection' and # instantiate it as a Model instance. Pre-9.0, the record object would # not remember that it came from 'other_collection', and attempts to # update it or reload it would fail unless you first remembered to # explicitly specify the collection every time. # # As of Mongoid 9.0, the record will remember that it came from # 'other_collection', and updates and reloads will automatically default # to that collection, for that record object. # legacy_persistence_context_behavior: false # When this flag is false, a document will become read-only only once the # #readonly! method is called, and an error will be raised on attempting # to save or update such documents, instead of just on delete. When this # flag is true, a document is only read-only if it has been projected # using #only or #without, and read-only documents will not be # deletable/destroyable, but they will be savable/updatable. # When this feature flag is turned on, the read-only state will be reset on # reload, but when it is turned off, it won't be. # legacy_readonly: false # The log level. # # It must be set prior to referencing clients or Mongo.logger, # changes to this option are not be propagated to any clients and # loggers that already exist. # # Additionally, only when the clients are configured via the # configuration file is the log level given by this option honored. # log_level: :info # Store BigDecimals as Decimal128s instead of strings in the db. # map_big_decimal_to_decimal128: true # Preload all models in development, needed when models use inheritance. # preload_models: false # When this flag is true, callbacks for every embedded document will be # called only once, even if the embedded document is embedded in multiple # documents in the root document's dependencies graph. # This is the default in 9.0. Setting this flag to false restores the # pre-9.0 behavior, where callbacks are called for every occurrence of an # embedded document. The pre-9.0 behavior leads to a problem that for multi # level nested documents callbacks are called multiple times. # See https://jira.mongodb.org/browse/MONGOID-5542 # prevent_multiple_calls_of_embedded_callbacks: true # Raise an error when performing a #find and the document is not found. # raise_not_found_error: true # Raise an error when defining a scope with the same name as an # existing method. # scope_overwrite_exception: false # Return stored times as UTC. # use_utc: false # Configure Driver-specific options. (optional) driver_options: # When this flag is off, an aggregation done on a view will be executed over # the documents included in that view, instead of all documents in the # collection. When this flag is on, the view filter is ignored. # broken_view_aggregate: true # When this flag is set to false, the view options will be correctly # propagated to readable methods. # broken_view_options: true # When this flag is set to true, the update and replace methods will # validate the parameters and raise an error if they are invalid. # validate_update_replace: false
基于版本的默认值
Mongoid 支持将特定版本的配置选项设置为默认值。这对于升级到新的 Mongoid 版本非常有用。升级 Mongoid 版本时,应在 Mongoid::Config
上设置以下内容:
Mongoid.configure do |config| config.load_defaults <OLD VERSION> end
这样,当升级到新版本的 Mongoid 时,您的代码将使用上一版本 Mongoid 的配置选项运行。 然后,您可以逐一更改新版本的功能标志,并测试您的代码是否仍按预期运行。 一旦考虑了所有新功能标志,就可以更改对load_defaults
的调用以接受新版本,并且可以删除所有已更改的功能标志。
例如,假设我们要从7.5升级到8.0 。 在这两个版本之间,添加了两个功能标志: legacy_attributes
和map_big_decimal_to_decimal128
。 在升级到 Mongoid 8之前,请将以下内容添加到Mongoid::Config
中:
Mongoid.configure do |config| config.load_defaults 7.5 end
在Gemfile
中升级到 Mongoid 8.0后,所有功能标志将保持为其7.5 默认行为: legacy_attributes: true,
map_big_decimal_to_decimal128: false
。 然后,您可以将这些功能标志逐一翻转到其8.0 行为:
Mongoid.configure do |config| config.load_defaults 7.5 config.legacy_attributes = false # config.map_big_decimal_to_decimal128 = true end
我们建议一次执行一个操作,因此在上面的示例中,我们将第二个标志注释掉。 验证代码在关闭legacy_attributes
标志的情况下按预期工作后,可以取消对map_big_decimal_to_decimal128
设置的注释。 一旦该功能也得到验证,就可以删除这两行,并将load_defaults
替换为:
Mongoid.configure do |config| config.load_defaults 8.0 end
ERb 预处理
加载配置文件时,Mongoid 会先使用 ERb 对其进行处理,然后将其解析为 YAML。由此能够实现的操作包括基于环境变量构建运行时配置文件的内容:
development: clients: default: uri: "<%= ENV['MONGODB_URI'] %>"
注意
从 ERb 输出值时,请确保这些值是有效的 YAML 并根据需要对其进行转义。
注意
由于 ERb 渲染是在 YAML 解析之前执行的,因此会评估配置文件中的所有 ERb 指令,包括 YAML 注释中出现的指令。
日志记录
对日志记录进行配置时,请务必记住:Mongoid 在 MongoDB Ruby 驱动程序之上提供了一个模型层,并且该驱动程序会将 CRUD 操作分派给 MongoDB 部署。因此,使用 Mongoid 的应用程序中有一些日志输出来自 Mongoid 本身,还有一些来自 Ruby 驱动程序。
Mongo 客户端是 Ruby 驱动程序客户端实例,因此 Mongo 客户端的记录器是 Ruby 驱动程序记录器,而不是 Mongoid 记录器。换言之,
# Ruby driver logger, not Mongoid logger Mongoid.client(:default).logger
根据 Ruby on Rails 应用程序中是否使用 Mongoid,以及 Mongoid 和 Ruby 驱动程序的配置方式,它们可能会使用相同的记录器实例或不同的实例(可能具有不同配置)。
在 Ruby on Rails 应用程序中
在 Ruby on Rails 应用程序中使用 Mongoid 时,默认情况下,Mongoid 会从 Rails 继承记录器和日志级别,并将驱动程序的记录器设置为同一记录器实例:
Rails.logger === Mongoid.logger # => true Mongoid.logger === Mongo::Logger.logger # => true
要更改日志级别,请使用 标准 Rails 配置 。将以下内容放入一个环境配置文件中,例如config/environments/production.rb
:
Rails.application.configure do config.log_level = :debug end
注意
当 Mongoid 在 Rails 应用程序中运行时,不使用log_level
Mongoid 配置选项,因为在这种情况下,Mongoid 会继承 Rails 的日志级别。
要以不同于 Rails 记录器的方式配置 Mongoid 或驱动程序记录器,请使用初始化程序,如下所示:
Rails.application.configure do config.after_initialize do # Change Mongoid log destination and/or level Mongoid.logger = Logger.new(STDERR).tap do |logger| logger.level = Logger::DEBUG end # Change driver log destination and/or level Mongo::Logger.logger = Logger.new(STDERR).tap do |logger| logger.level = Logger::DEBUG end end end
注意
目前,Ruby 标准库 Logger
中没有任何预配可以返回记录器正在使用的日志设备(即 IO
对象)。例如,要将 Mongoid 和/或 Ruby 驱动程序记录到标准 Rails 日志文件(例如 log/development.log
),但采用的日志级别不同于标准 Rails 记录器 (Rails.logger
),则必须单独打开该文件,并将生成的 IO
对象传递给 Logger
构造函数。
注意
由于默认情况下 Mongoid 会将其自己的记录器和驱动程序的记录器设置为与 Rails 记录器相同的实例,因此修改其中任一实例都会影响所有这三个实例。例如,以下代码会更改所有三个记录器的日志级别,除非应用程序如上所述将单独的 Logger
实例分配给 Mongo::Logger.logger
:
Mongoid::Logger.logger.level = Logger::DEBUG
独立运行的实例
当未加载到 Ruby on Rails 应用程序中时,Mongoid 会遵循log_level
顶级配置选项。 它可以在配置文件中给出,如下所示:
development: clients: default: # ... options: log_level: :debug
……或者在配置 Mongoid inline 时:
Mongoid.configure do |config| config.log_level = :debug end
Mongoid 7.1 及更高版本中的默认日志目标是标准错误。Mongoid 7.0 及更低版本中的默认日志目标是标准输出。要更改日志目标,请按以下步骤创建新记录器实例:
Mongoid.logger = Logger.new(STDERR).tap do |logger| logger.level = Logger::DEBUG end
要更改 Ruby 驱动程序日志级别或目标:
Mongo::Logger.logger = Logger.new(STDERR).tap do |logger| logger.level = Logger::DEBUG end
要对驱动程序记录器采用与 Mongoid 记录器相同的设置,请执行以下操作:
Mongo::Logger.logger = Mongoid.logger
注意
以独立模式运行时,Mongoid 不会更改驱动程序的记录器。
时区
Mongoid 使用 ActiveSupport 的时区功能,该功能比 Ruby 的标准库更加强大。 重要的是,ActiveSupport 允许配置Time.zone
,这是一个线程全局变量,为处理日期和时间值提供上下文。
虽然在 Ruby 中对时区的全面处理超出本教程的范围,但要实现正确的时区处理,最简单可靠的方法如下:
将操作系统的时区设置为 UTC。例如,在 Linux 上:
cp /usr/share/zoneinfo/UTC /etc/localtime
将应用程序默认时区域设置为 UTC:
# If using Rails, in application.rb: class Application < Rails::Application config.time_zone = 'UTC' end # If not using Rails: Time.zone = 'UTC'
在每个控制器和作业类中,尽早在
before_filter
中设置适当的时区。 例如,如果应用程序的每个用户都可以设置自己的时区,您可能希望执行以下操作:
class ApplicationController < ActionController::Base before_filter :fetch_user, :set_time_zone def set_time_zone Time.zone = @user.time_zone end end
从这里开始,您可以自然地使用当地时区的时间。 例如,在视图中:
Turned into a pumpkin after <%= cinderella.updated_at.seconds_after_midnight %> seconds!
使用 ActiveSupport 方法而不是 Ruby 标准库。
Time.zone.now
orTime.current` instead of ``Time.now
Date.current
而不是Date.today
请务必注意,后面的Ruby标准库方法会引用您的系统时区域(例如 UTC),而不是
Time.zone
的值。 由于很容易弄错这些名称相似的方法,因此我们建议使用 Rubocop 的 Rails/TimeZone cop 在您的 CI 中。
为从 MongoDB 加载的数据设置时区
MongoDB以 UTC 格式存储所有时间,不包含时区域信息。 Mongoid 模型会加载并返回时间值作为ActiveSupport::TimeWithZone
的实例。 您可以设立use_utc
选项来控制 Mongoid 在从数据库加载时如何设置时区域:
如果为 false(默认值),Mongoid 将使用
Time.zone
来设置从数据库加载的时间值的时区。如果为 true,Mongoid 将始终将加载的时间值的时区设置为 UTC。
use_utc
只影响数据的加载方式,不影响数据的持久化。 例如,如果将Time
或ActiveSupport::TimeWithZone
实例分配给时间字段,则始终使用所分配实例的时区信息,而不考虑use_utc
设置。 或者,如果将string值分配给时间字段,则将使用string中的任何时区信息(如果存在)。 如果string不包含时区信息,将根据 Time.zone
进行解析。 举例说明:
Time.use_zone("Asia/Kolkata") do # String does not include time zone, so "Asia/Kolkata" will be used ghandi.born_at = "1869-10-02 7:10 PM" # Time zone in string (-0600) will be used amelia.born_at = "1897-07-24 11:30 -0600" end
配置 SSLContext
可能需要在应用程序中进一步配置 TLS 选项,例如启用或禁用某些密码。
这可以通过在 Ruby 驱动程序上设置 TLS 上下文钩子来实现 — TLS 上下文钩子是用户提供的Proc
,它们将在驱动程序中的任何 TLS 套接字连接之前调用,并可用于修改底层OpenSSL::SSL::SSLContext
套接字使用的对象。
要设置 TLS 上下文钩子,请将Proc
添加到Mongo.tls_context_hooks
数组。 这可以在初始化程序中完成。 以下示例添加了一个仅启用“AES 256 -SHA”密码的钩子。
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
对象作为其唯一参数。这些过程将在套接字创建期间按顺序执行。
警告
TLS 上下文钩子是全局性的,会影响应用程序中的所有 Mongo::Client
实例。
有关 TLS 上下文钩子的详情,包括分配和删除此类钩子的最佳实践,请参阅 Ruby 驱动程序文档。
网络压缩
Mongoid 支持压缩传入和传出MongoDB服务器的消息。 此功能由Ruby驾驶员提供,该驱动程序实施MongoDB服务器支持的三种算法:
Snappy :当连接到以
snappy
开头的 MongoDB 服务器时,可以使用3 压缩。4发布,并需要 snappy 要安装的库。zlib:当连接到以
zlib
MongoDB开头的 服务器时,可以使用3 压缩。6发布。Zstandard :当连接到以
zstd
开头的 MongoDB 服务器时,可以使用4 压缩。2发布,并需要 zstd-Ruby 要安装的库。
要使用传输协议压缩,请在mongoid.yml
中配置 Ruby 驱动程序选项:
development: # Configure available database clients. (required) clients: # Define the default client. (required) default: # ... options: # These options are Ruby driver options, documented in # https://mongodb.com/zh-cn/docs/ruby-driver/current/reference/create-client/ # ... # Compressors to use. (default is to not use compression) # Valid values are zstd, zlib or snappy - or any combination of the three compressors: ["zstd", "snappy"]
如果没有显式请求压缩程序,则即使系统上存在一个或多个压缩程序所需的依赖项,驱动程序也不会使用压缩。
驾驶员会选择所请求的第一个压缩程序,而服务器也支持该压缩程序。 建议使用zstd
压缩器,因为与其他压缩器相比,它可以在相同的 CPU 消耗下产生最高的压缩率。
为了最大限度地提高服务器兼容性,可以指定所有三个压缩程序,例如指定为compressors: ["zstd", "snappy", "zlib"]
。
客户端加密
加载配置文件时,Mongoid 允许该文件包含 BSON::Binary
实例,这些实例用于在模式映射中指定 keyId
以进行客户端加密,如以下示例所示:
development: clients: default: database: blog_development hosts: [localhost:27017] options: auto_encryption_options: key_vault_namespace: 'keyvault.datakeys' kms_providers: local: key: "z7iYiYKLuYymEWtk4kfny1ESBwwFdA58qMqff96A8ghiOcIK75lJGPUIocku8LOFjQuEgeIP4xlln3s7r93FV9J5sAE7zg8U" schema_map: blog_development.comments: properties: message: encrypt: keyId: - !ruby/object:BSON::Binary data: !binary |- R/AgNcxASFiiJWKXqWGo5w== type: :uuid bsonType: "string" algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" bsonType: "object"
与分叉服务器一起使用
将 Mongoid 与分叉 Web服务器(例如 Puma)或任何以其他方式分叉以生成子进程的应用程序一起应用时,需要特殊注意事项。
如果可能,我们建议在分叉之前不要在父进程中执行任何MongoDB操作,这样可以避免任何与分叉相关的陷阱。
driver's "Usage with Forking Servers" documentation
<https://www.mongodb.com/zh-cn/docs/ruby-driver/current/reference/create-client/#usage-with-forking-servers>
中提供了有关mongo Ruby驱动程序如何处理分叉的详细技术说明。 简而言之,为避免Mongo::Error::SocketError
和Mongo::Error::NoServerAvailable
等各种连接错误,您必须执行以下操作:
在使用
Mongoid.disconnect_clients
进行分叉之前,立即断开父 Ruby 进程中 MongoDB 客户端的连接。 这可确保父进程和子进程不会意外重复使用相同的套接字并发生 I/O 冲突。 请注意,Mongoid.disconnect_clients
不会中断任何正在进行的 MongoDB 操作,并且会在您执行新操作时自动重新连接。使用
Mongoid.reconnect_clients
进行分叉后,立即重新连接 Ruby 子进程中的 MongoDB 客户端。 这是在子进程中重新生成驱动程序的监控线程所必需的。
大多数 Web 服务器都提供钩子,应用程序可以使用这些钩子在工作进程分叉时执行操作。 以下是几种常见Ruby Web 服务器的配置示例。
Puma
on_worker_boot
使用before_fork
on_refork
钩子重新连接工作线程中的客户端,并使用 和 钩子关闭父进程中的客户端 ( Puma 文档 )。
# config/puma.rb # Runs in the Puma master process before it forks a child worker. before_fork do Mongoid.disconnect_clients end # Required when using Puma's fork_worker option. Runs in the # child worker 0 process before it forks grandchild workers. on_refork do Mongoid.disconnect_clients end # Runs in each Puma child process after it forks from its parent. on_worker_boot do Mongoid.reconnect_clients end
Unicorn
使用 after_fork
钩子重新连接工作进程中的客户端,并使用 before_fork
钩子关闭父进程中的客户端(Unicorn 文档):
# config/unicorn.rb before_fork do |_server, _worker| Mongoid.disconnect_clients end after_fork do |_server, _worker| Mongoid.reconnect_clients end
Passenger
使用 starting_worker_process
钩子重新连接工作进程中的客户端(Passenger 文档)。在工作进程分叉之前,Passenger 中似乎不会出现在父进程中调用的钩子。
if defined?(PhusionPassenger) PhusionPassenger.on_event(:starting_worker_process) do |forked| Mongoid.reconnect_clients if forked end end
查询缓存中间件
为机架 Web 请求启用查询缓存
MongoDB Ruby驱动程序提供了一个 Rack 中间件,该中间件在每个网络请求期间启用查询缓存。 以下示例了如何在Ruby on Rails应用程序中启用查询缓存中间件:
# config/application.rb # Add Mongo::QueryCache::Middleware at the bottom of the middleware stack # or before other middleware that queries MongoDB. config.middleware.use Mongo::QueryCache::Middleware
请参阅 Rails on Rack 指南 有关在 Rails 应用程序中使用 Rack 中间件的更多信息。
为 ActiveJob 启用查询缓存
MongoDB Ruby驱动程序还为 ActiveJob 提供查询缓存中间件。 您可以在初始化程序中为所有作业启用它:
# config/initializers/active_job.rb # Enable Mongo driver query cache for ActiveJob ActiveSupport.on_load(:active_job) do include Mongo::QueryCache::Middleware::ActiveJob end
或者对于特定的作业类别:
class MyJob < ActiveJob::Base include Mongo::QueryCache::Middleware::ActiveJob end
开发配置
驱动程序的默认配置适用于生产部署。在开发过程中,可以对某些设置进行调整,以提供更好的开发体验。
:server_selection_timeout
:如果您的 MongoDB Server 在本地运行,并且您会手动启动它,请将此值设置为较低的值(例如1
)。如果没有服务器正在运行,则较低的服务器选择超时会导致驱动程序快速失败。
建议的开发配置示例:
development: clients: default: database: mongoid hosts: - localhost:27017 options: server_selection_timeout: 1