我们发现,问题的原因是有自定义的Resque.before_fork
和Resque.after_fork
处理程序。
NewRelic的RPM gem会自动设置与Resque.before_fork
和Resque.after_fork
相关的钩子,以建立工作进程之间的通信渠道。由于Resque的限制,它仅运行最后一个分配给before_fork和after_fork钩子的块/Proc。因此,如果您有自己的自定义before_fork/after_fork钩子,则*必须*手动设置代理的通信通道,例如在config / initializers / custom_resque.rb文件中:
Resque.before_fork do |job|
NewRelic::Agent.register_report_channel(job.object_id)
# extra custom stuff here
end
Resque.after_fork do |job|
NewRelic::Agent.after_fork(:report_to_channel => job.object_id)
# extra custom stuff here
end
这段代码直接来自于RPM gem的文件 gems/newrelic_rpm-3.5.0/lib/new_relic/agent/instrumentation/resque.rb
2012年12月27日RPM bug更新: 在部署上述技术后,我们发现当在forked模式下(例如Resque)使用RPM gem时,它会泄漏文件句柄。我们观察到以下类型的错误消息:ActiveRecord :: StatementInvalid:ArgumentError: fdsets太大:将client_min_messages设置为''
。经过大量挖掘,我们发现当连接到数据库并且文件描述符数量耗尽时,这些错误是由ActiveRecord引起的。New Relic确认了采样explain计划时代理存在一个bug。当运行大量连接到数据库的Resque作业时,就会发生这种情况。
2013年1月28日Bug更新: 经过很多思考,我们发现这个bug是由与resque-lonely_jobgem的不支持交互引起的,它使用Resque的before_perform
hook 可以通过Resque::Job::DontPerform
异常停止一个Resque工作任务。在这种情况下,RPM客户端不能正常清理并且会泄漏文件描述符。 New Relic已被告知并正在修复这个问题。
2013年4月10日Bug更新:此问题已得到解决。我们正在使用3.6.0.78,它可以处理此情况。不再泄漏文件描述符!谢谢New Relic。
Resque :: Job :: DontPerform
的任何地方调用NewRelic :: Agent.shutdown
以避免异常抛出。 - Liron Yahdavresque-lonely_job
的问题,自代理版本3.6.0起。 - grumbler我遇到了同样的问题,因为New Relic代理程序没有在我的Resque工作者中启动。所以我更新了我的resque:setup
rake任务,手动启动代理程序:
task "resque:setup" => :environment do
if ENV['NEW_RELIC_APP_NAME']
NewRelic::Agent.manual_start :app_name => ENV['NEW_RELIC_APP_NAME']
end
end
ENV['NEW_RELIC_APP_NAME']
变量应该会自动设置。 - trlinerrake aborted!
undefined local variable or method `establish_connection' for ActiveRecord::Base:Class
有更简单的解决方案,只需将NEWRELIC_ENABLE环境变量添加到您的heroku实例中,一切都应该正常工作:
heroku config:set NEWRELIC_ENABLE=true