gpt4 book ai didi

ruby-on-rails - rails +运动鞋 : could not obtain a connection from the pool

转载 作者:数据小太阳 更新时间:2023-10-29 08:06:40 26 4
gpt4 key购买 nike

我们在大型应用程序的生产中使用 Sneakers gem。有时负载可能非常大,以至于一个特定队列可能包含超过 250_000 条消息。在这种情况下,异常

ActiveRecord::ConnectionTimeoutError: 
could not obtain a connection from the pool within 5.000 seconds (waited 5.000 seconds); all pooled connections were in use

定期发生。

对于数据库,我们使用基于 PostgreSQL 9.6 的 Amazon RDS。 max_connections PostgreSQL 配置值为 3296。

我们的database.yml 文件:

production:
adapter: postgresql
encoding: utf8
pool: 40
database: <%= ENV['RDS_DB_NAME'] %>
username: <%= ENV['RDS_USERNAME'] %>
password: <%= ENV['RDS_PASSWORD'] %>
host: <%= ENV['RDS_HOSTNAME'] %>
port: <%= ENV['RDS_PORT'] %>

我想我们可以增加一个pool值,但我找不到关于如何计算最大可能值的信息,所以它不会破坏任何东西。

此外,使用 Sneakers gem 进行后台处理的应用程序的副本单独存在(但使用相同的数据库)并且可以单独配置。但现在它具有相同的 database.yml 配置。运动鞋 gem 配置文件:

production:
heartbeat: 2000
timeout_job_after: 35
exchange_type: :fanout
threads: 4
prefetch: 4
durable: true
ack: true
daemonize: true
retry_max_times: 5
retry_timeout: 2000
workers: 4

我们在基本运行时应用程序中的连接池没有问题,但是 ActiveRecord::ConnectionTimeoutError 经常发生在 workers 中,这是一个非常大的问题。

所以,请帮我重新配置databese.yml文件:

  1. 如何正确计算 pool 选项的最大可能值如果数据库 max_connections 值为 3296?
  2. 如何正确计算 pool 选项的最大可能值将 Sneakers gem 与上述配置一起使用时?
  3. 或者,如果我的配置很好,我怎样才能避免 worker 中的 ActiveRecord::ConnectionTimeoutError

提前致谢。

最佳答案

在等待答案的同时,我一直在寻找解决方案。

而且,我想,我最基本的问题是连接池大小。

在运动鞋 gem 问题跟踪器上,我发现了一个 comment使用计算满载时所需连接数的公式。我稍微更改了评论中的代码,所以现在它会考虑每个工作人员的个人设置进行计算:

before_fork = -> {
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.connection_pool.disconnect!
Sneakers.logger.info('Disconnected from ActiveRecord!')
end
}

after_fork = -> {
def count_pool_size
workers = ::Sneakers::Worker::Classes
default_threads_size = ::Sneakers.const_get(:CONFIG)[:threads]
base_pool_size = 3 + workers.size * 3

if Sneakers.const_get(:CONFIG)[:share_threads]
base_pool_size + default_threads_size
else
base_pool_size + connections_per_worker(workers, default_threads_size)
end
end

def connections_per_worker(classes, default)
classes.inject(0) do |sum, worker_class|
sum + (worker_class.queue_opts[:threads] || default)
end
end

def reconfig?
Rails.env.production?
end

ActiveSupport.on_load(:active_record) do
config = Rails.application.config.database_configuration[Rails.env]
config.merge!('pool' => count_pool_size) if reconfig?

ActiveRecord::Base.establish_connection(config)
Sneakers.logger.info("Connected to ActiveRecord! Config: #{config}")
end
}

总结:对于所有工作人员,我需要在最大负载下限制近 600 个连接。但我只有 40 个。现在,我将使用上面的代码。希望这会有所帮助。

关于ruby-on-rails - rails +运动鞋 : could not obtain a connection from the pool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55229693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com