Ruby on rails Rails:如何调试本地主机不响应延迟的\u作业/工头

Ruby on rails Rails:如何调试本地主机不响应延迟的\u作业/工头,ruby-on-rails,delayed-job,foreman,Ruby On Rails,Delayed Job,Foreman,我有一个创建新activerecord记录的任务,我最近使用delayed_job和foreman将其转移到后台任务 有时这可以正常工作,但有时会导致浏览器中的Rails应用程序停止响应 此时,我可以从数据库中看到,所有延迟的作业都已完成,所有新记录都已创建 然而,当我终止进程时,我得到了更多11200行的终端输出。这主要包括通过web进程在模型上执行两个方法,这两个方法都涉及对数据库的调用: validate :hit_database_to_see_if_model_exists? bef

我有一个创建新activerecord记录的任务,我最近使用delayed_job和foreman将其转移到后台任务

有时这可以正常工作,但有时会导致浏览器中的Rails应用程序停止响应

此时,我可以从数据库中看到,所有延迟的作业都已完成,所有新记录都已创建

然而,当我终止进程时,我得到了更多11200行的终端输出。这主要包括通过web进程在模型上执行两个方法,这两个方法都涉及对数据库的调用:

validate :hit_database_to_see_if_model_exists?

before_save :get_rows_from_database_and_perform_calculation  
还有一些INSERT语句,我确信它们已经进入数据库,因为在终止进程之前/之后,记录的数量没有改变

这是我的文件:

web:bundle exec rails服务器精简版-p$PORT-e$RACK\u ENV

工人:bundle exec rake作业:工作

所以感觉就像我得到了一个“堆栈溢出”(woop)。你能否解释一下:

  • 一般情况如何
  • Rails中发生“堆栈溢出”的位置
  • 这些事情是在我点击“Ctrl+C”后发生的,还是在此时打印到终端上
  • 这可能是什么原因造成的
  • 我如何调试/修复它
更新

看起来有些任务是由后台任务分配给web进程的,但在浏览器被“刺激”之前不会执行。在某些情况下,这些任务都会执行,但如果任务太多,应用程序就会崩溃。你知道是什么引起的吗

更新

我尝试在两个单独的窗口中运行web和worker进程

在这种情况下,我无法复制浏览器挂起的问题,并且在每种情况下工作进程都正确完成

然而,我做了一个有趣的观察,如果我不触摸浏览器,那么在web窗口中就不会显示任何输出。但是,如果我触摸浏览器,那么web窗口中会出现数千行工作进程当时正在执行的操作

这正常吗?这是否揭示了问题的症结所在

更新

在我终止进程后的终端输出的底部,它显示“Killed:9”

07:45:21系统|向所有进程发送SIGKILL

死亡人数:9人

这9到底指的是什么?这不寻常吗

更新

我正在使用:

  • 延迟作业3.0.4
  • 延迟工作活动记录0.3.3
  • 延迟作业web 1.1.2
  • 工头0.60.2
分辨率


感谢@Justin下面的回答(和)。看起来Ruby缓冲区在默认情况下是stdout,并且该缓冲区溢出,导致应用程序停止响应。我在config/environments/development.rb的顶部添加了
$stdout.sync=true
,问题似乎已经解决了。

这只是部分答案,但可能有助于调试

默认情况下,Rails缓冲日志记录,并在每次web请求后刷新日志记录。一种选择是简单地用

你也可以

你还必须小心STDOUT。在我当前的项目中,我在
config.ru
和我的后台启动中都启用了stdout flushing(我使用的是sidekiq,所以启动过程可能有点不同)

至于你更大的问题,, 我很惊讶rails进程正在运行后台任务。是否有一个选项可以禁用它,至少在实验中是这样


还有标准的调试工具——save上的所有数据库调用让我担心,所以我会尝试各种组合禁用它们,看看是否有什么改进。特别是对于其中两个,例如,如果您的before_save钩子更改了模型中的值,则可能会触发验证;如果这重置了before_save钩子,您将有一个循环。

只是想澄清一下,您使用的是哪个版本的delayed_job和foreman?我想我在foreman和sidekiq中遇到过这个问题。在我刷新页面或从浏览器ping服务器之前,后台作业日志不会显示出来。所以,这可能意味着这是与foreman有关的。Justin-谢谢这些伟大的指点。我会更新我的问题,如果我得到它的底部。同时,+50;-)贾斯汀-你说得对。启用标准输出刷新后,问题似乎已解决。非常感谢!很乐意帮忙。仅供参考:出于性能原因,输出通常是缓冲的-我还没有得到一个高需求的应用程序,但如果你有大量的流量,这可能是一个问题。
Rails.logger = Logger.new(STDOUT)
Rails.logger.auto_flushing = (Rails.env.development? || Rails.env.test?)
STDOUT.sync = true