【发布时间】:2019-03-18 20:38:52
【问题描述】:
我们将 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_connectionsPostgreSQL 配置值为 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 经常出现在工作人员中,这是一个非常大的问题。
所以,请帮我重新配置databese.yml文件:
- 如何正确计算
pool选项的最大可能值 如果数据库max_connections的值为3296? - 如何正确计算
pool选项的最大可能值 当使用带有上述配置的 Sneakers gem 时? - 或者,如果我的配置不错,如何避免在工作人员中使用
ActiveRecord::ConnectionTimeoutError?
提前致谢。
【问题讨论】:
-
您应该提供您正在使用的 Rails 版本。如果您使用的是 Rails 5+,您可以尝试将您的应用程序代码包装在
Rails.application.executor { }中(中间件或只是在您的工作中硬编码)。我没有使用 Sneakers 的经验,但我怀疑它不会自行释放与池的连接,应该可以解决它。有关该机制的更多详细信息:guides.rubyonrails.org/threading_and_code_execution.html。请告诉我进展如何。 -
@SvetlinSimonyan 我正在
ActiveRecord::Base.connection_pool.with_connection块内执行工作人员的代码。如果我没记错的话,Rails.application.executor.wrap在后台使用它。
标签: ruby-on-rails ruby postgresql rabbitmq sneakers