我们有一个在 Heroku 上运行 resque workers 的应用程序。我们已经安装了 New Relic 插件,根据文档,New Relic Agent 应该自动检测 resque 工作人员。但是,我们在 New Relic 仪表板上的“后台作业”选项卡上没有看到任何输出。
根据相同的文档,我们没有触及newrelic.yml
文件。我们既不确定出了什么问题,也不确定如何有效地调试它。我们需要做什么?
事实证明,我们的问题是由我们自己的自定义Resque.before_fork
和Resque.after_fork
处理程序引起的。
NewRelic 的 RPM gem 将自动设置挂钩Resque.before_fork
并Resque.after_fork
为工作人员建立沟通渠道。作为 Resque 的限制,它仅将最后分配的块/Proc 运行到 before_fork 和 after_fork 挂钩。因此,如果您有自己的自定义 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
RPM 错误更新 12/27/2012:部署上述技术后,我们发现 RPM gem 在分叉模式下使用时会泄漏文件句柄(例如 Resque)。我们观察到了这种错误信息ActiveRecord::StatementInvalid: ArgumentError: too large fdsets: SET client_min_messages TO ''
。经过大量挖掘,我们发现这些是由于 ActiveRecord 尝试打开数据库连接而无法打开数据库连接时造成的,因为文件描述符的数量已用尽。New Relic 在对解释计划进行抽样时确认代理存在错误。当运行大量连接到数据库的 Resque 作业时会发生这种情况。
错误更新 2013 年 1 月 28 日:经过多次摸索后,我们发现这个错误是由与resque-lonely_job gem 的不受支持的交互引起的,该 gem 使用了 Resque 的before_perform
钩子,可能会在Resque::Job::DontPerform
异常情况下停止 Resque 作业。在这种情况下,RPM 客户端无法正确清理并泄漏文件描述符。New Relic 已被告知并正在修复。
错误更新 2013 年 4 月 10 日:已修复。我们使用的是 3.6.0.78,它可以处理这种情况。不再有文件描述符泄漏!谢谢新遗物。
我遇到了同样的问题,因为 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
尝试了@trliner 的建议,但我一直收到此错误:
rake aborted!
undefined local variable or method `establish_connection' for ActiveRecord::Base:Class
有更简单的解决方案,只需将 NEWRELIC_ENABLE env 添加到您的 heroku 实例中,一切都应该工作:
heroku config:set NEWRELIC_ENABLE=true