Sidekiq getting ActiveRecord::ConnectionTimeoutError:无法从池中获取



我在Sidekiq的后台工作得到一个ActiveRecord::ConnectionTimeoutError: could not obtain a connection from the pool例外

配置

  • 我有一个PUMA web进程和一个SIDEKIQ进程运行在Heroku (2 hobby dynos) [Rails应用程序与后台作业]

  • database.yml中我有pool: 40(在defaultproduction中)

  • sidekiq.yml我有:concurrency: 7

  • puma.rb中,我有max_threads_count = ENV.fetch("PUMA_MAX_THREADS") { 5 }并设置了ENV["PUMA_MAX_THREADS"] = 5

  • 我正在使用一个Heroku pgsql业余爱好实例,它允许20 connections

预期行为

当7个Sidekiq worker忙于运行作业时,它们应该有足够的可用db连接。

因为:

需要的数据库连接:

  • 5 for 5 PUMA线程
  • 12: [7 + 5] for SIDEKIQ threads (7 workers + 5 for redis?)-不确定背后的原因)
  • 总需求:17 [12+5]
  • 可用总数:20

实际行为

当7个Sidekiq工人忙于运行作业时,2个作业失败并引发ConnectionTimeOutError(总是2个作业,因此实际最大并发数为5)

STUFF I observed (MIGHT HELP):

  • 在SIDEKIQ仪表板中,Redis连接达到最大10(从未更高)[我猜5线程+ 5]

  • 在Heroku db中,当大量作业排队时,连接数总是远低于可用的20个(所以pgsql实例没有问题)

任何帮助或建议将是超级感激:))

提前感谢!

更新:添加database.yml文件

default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("DB_POOL") { 10 } %>
development:
<<: *default
database: tracker_app_development
test:
<<: *default
database: tracker_app_test
production:
url: <%= ENV['DATABASE_URL'] %>
pool: <%= ENV.fetch("DB_POOL") { 10 } %>
web: DB_POOL=$PUMA_MAX_THREADS bundle exec puma -C config/puma.rb
worker: DB_POOL=14 bundle exec sidekiq -C config/sidekiq.yml
release: rake db:migrate

此异常是从Rails中的ActiveRecord::ConnectionAdapters::ConnectionPool::Queue类引发的,特别是在该类的poll方法中,该方法接受超时时间(默认为5s)。错误是这样被引发的:

if elapsed >= timeout
msg = "could not obtain a connection from the pool within %0.3f seconds (waited %0.3f seconds); all pooled connections were in use" %
[timeout, elapsed]
raise ConnectionTimeoutError, msg
end

我认为这是在说,如果从它尝试获得连接以来经过的时间大于提供的超时(默认为5s),那么它将引发此异常。发生这种情况是因为池中的可用连接数为10,而在Sidekiq中,您提到的默认池大小为14。尝试将web动态分析器的池大小增加到大于或等于Sidekiq动态分析器中指定的默认池连接数。

如果这不起作用,那么您可以尝试将checkout_timeout从5s增加到更长的持续时间,如下所示:

default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("DB_POOL") { 10 } %>
checkout_timeout: 10
development:
<<: *default
database: tracker_app_development
test:
<<: *default
database: tracker_app_test
production:
url: <%= ENV['DATABASE_URL'] %>
pool: <%= ENV.fetch("DB_POOL") { 10 } %>

这是Rails的API文档对ConnectionPools的解释

https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

解决方案发现:

在我的database.yml文件中,production配置有1个缩进,而它应该有0…

相关内容

  • 没有找到相关文章

最新更新