如何在Heroku上运行时使用New Relic监控Resque工作者?

7
我们有一个在Heroku上运行resque workers的应用程序。我们安装了New Relic附加组件,根据文档,New Relic Agent应该自动对resque workers进行仪表化。然而,在New Relic仪表板的“后台作业”选项卡上没有看到任何输出。
根据同一文档,我们没有触及newrelic.yml文件。我们不确定出了什么问题,也不知道如何有效地进行调试。我们需要做什么?

在您的 Resque 工作程序日志中,您是否看到了 New Relic 代理连接? - jakeonrails
3个回答

11

我们发现,问题的原因是有自定义的Resque.before_forkResque.after_fork处理程序。

NewRelic的RPM gem会自动设置与Resque.before_forkResque.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。


3
我在New Relic工作,这完全正确。我们将来会更新文档,以使其更清晰易懂。感谢你发现这个问题。 - jasonrclark
3
这里有一份文档描述了 before_fork / after_fork 钩子函数的使用:https://newrelic.com/docs/ruby/resque-instrumentation关于文件描述符泄漏问题 - 实际上与解释计划功能无关,只在特定情况下发生。但我认为我们现在已经理解了它,并正在努力解决。 - grumbler
1
关于2013年1月28日的错误更新,我们已经与New Relic支持团队联系,并且他们表示需要一些时间才能提供修复该问题的新版本。在此期间,您可以通过monkeypatching来解决该问题,即在引发Resque :: Job :: DontPerform的任何地方调用NewRelic :: Agent.shutdown以避免异常抛出。 - Liron Yahdav
进一步的错误更新:我们现在已经修复了resque-lonely_job的问题,自代理版本3.6.0起。 - grumbler
我可以确认,最新的New Relic gem更新已经解决了这个问题。感谢New Relic在此事上的响应! - Wolfram Arnold

4

我遇到了同样的问题,因为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  

是的,如果您安装了New Relic Heroku插件,则ENV['NEW_RELIC_APP_NAME']变量应该会自动设置。 - trliner

1
尝试了@trliner的建议,但我一直收到这个错误:
rake aborted!
undefined local variable or method `establish_connection' for ActiveRecord::Base:Class

有更简单的解决方案,只需将NEWRELIC_ENABLE环境变量添加到您的heroku实例中,一切都应该正常工作:

heroku config:set NEWRELIC_ENABLE=true

很奇怪,我的解答对你没有起作用,但我认为你的解决方案更好。出于好奇,你使用的是哪个Heroku栈? - trliner
我接受得太快了。那并没有起作用。New Relic代理还会自动检测Resque。当我们将开发机器指向与Heroku实例相同的NR凭据时,我们可以看到发送的事件。然而,一旦代码部署后,它就不会发送事件... - Wolfram Arnold
这个解决方案对我有用,但我没有任何 before_fork 或 after_fork 的东西。 - djburdick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接