Joe*_*Joe 5 activerecord ruby-on-rails sidekiq rails-activejob
我遇到了Sidekiq工人的问题.
ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
Run Code Online (Sandbox Code Playgroud)
我正在遵循有关使用ActiveRecord::ConnectionTimeoutError和适当大的连接池的建议.
我想知道我是否正在耗尽连接池.我记录size和connections.length从ActiveRecord::Base.connection_pool,但他们留在一个恒定的大小= 100 connections.length = 5,这表明这不是一个资源泄漏问题.
我的MySQL服务器配置为允许最多400个并发连接.
我的工作最终看起来像这样:
class MyJob < ActiveJob::Base
queue_as :default
rescue_from StandardError do |exception|
# clear connections on exception. Not sure if this is a good idea or not.
ActiveRecord::Base.clear_active_connections!
end
def perform()
logger.info "size"
logger.info ActiveRecord::Base.connection_pool.instance_eval { @size }
logger.info "connections"
logger.info ActiveRecord::Base.connection_pool.instance_eval { @connections }.length
# Ensure connections come from connection pool.
ActiveRecord::Base.connection_pool.with_connection do |conn|
# do stuff
end
end
end
Run Code Online (Sandbox Code Playgroud)
这是诊断造成这种情况的正确方法,无论是资源匮乏还是泄漏?是否有其他技术可以解决为什么会发生这种情况?
尝试 ActiveRecord::ConnectionAdapters::ConnectionPool#stat
ActiveRecord::Base.connection_pool.stat
# => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
Run Code Online (Sandbox Code Playgroud)
来自connection_adapters/abstract/connection_pool.rb,在 activerecord 5.2.2.1 中。
这ActiveRecord::ConnectionTimeoutError可在我看来只发生在一个场景-当有这么多线程想要使用DB连接,游泳池是疲惫,甚至等待空闲连接不帮助(从学源代码)。
在你的情况下,这很奇怪。您仅使用 25 个工作线程,但池设置为 100 个连接,因此有足够的储备。我仍然怀疑您必须在某处生成线程。也许你在你的工作中做了一些线程?也许您使用 gem 在您的工作中创建线程?
无论如何,如果您能够重现异常,我建议捕获它并在它发生时获取所有线程的列表,如下所示:
begin
# job stuff...
rescue ActiveRecord::ConnectionTimeoutError
puts "listing #{Thread.list.count} threads:"
Thread.list.each_with_index do |t,i|
puts "---- thread #{i}: #{t.inspect}"
puts t.backtrace.take(5)
end
end
Run Code Online (Sandbox Code Playgroud)
我预计会有 100 个或更多线程,您应该看到它们从回溯中被卡住的确切位置。
| 归档时间: |
|
| 查看次数: |
2311 次 |
| 最近记录: |