Elastic Beanstalk 上的 Sidekiq 进程 - Errno::ENOENT:没有这样的文件或目录 - getcwd

Posted

技术标签:

【中文标题】Elastic Beanstalk 上的 Sidekiq 进程 - Errno::ENOENT:没有这样的文件或目录 - getcwd【英文标题】:Sidekiq process on Elastic Beanstalk - Errno::ENOENT: No such file or directory - getcwd 【发布时间】:2015-11-30 01:40:50 【问题描述】:

我们正在使用 rest-client 在 Sidekiq 工作人员上发送外部 API 请求,这些工作人员在我们的 Elastic Beanstalk 管理的 EC2 实例上启动 as a process。

Dir.home 失败时,rest-client 使用 netrc 和 netrc calls Dir.pwd。我们偶尔会看到此错误:

Errno::ENOENT: No such file or directory - getcwd
[GEM_ROOT]/gems/netrc-0.10.3/lib/netrc.rb:26 :in `pwd`

这表明ENV['HOME']没有设置,显然当前目录不再存在。通常,HOME 已在 EB 实例上设置,我们已尝试通过 eb setenv 设置它以确保安全。

问题是这种情况如何在 EB 上出现,以及我们将来如何避免这种情况。我犹豫不决,但也许我们没有在部署之间正确杀死 Sidekiq 进程,并且旧的 sidekiq 进程仍然存在,引用旧目录?我对EB还不是很熟悉;任何指导将不胜感激。

【问题讨论】:

【参考方案1】:

正如问题和一些答案所预示的,这是一个避免终止的流氓进程,在这种情况下,由于我们早期部署中的一个粗心的配置更改。我们sidekiq.config的第30行控制了进程的数量,我们从2降到1但是没有在改动后手动从服务器中移除第二个进程。

这个故事的寓意是,Sidekiq 进程不仅在部署期间容易受到意外行为的影响。即使没有在多个部署中停止/启动,我们的错误进程也很高兴地完成了工作,但是任何依赖于 Dir.pwd 的任何脚本以及可能需要 ENV 数据的任何其他脚本都会在稳定部署后失败在持久化进程上运行。

如果您看到此类故障,请绝对肯定您之前的部署中没有运行意外进程。这意味着确保它们在部署期间被正确终止as @JeffD23 mentioned,但同时还要确保您没有从过去的部署中挂起。

【讨论】:

我也有同样的问题。我已经怀疑这是原因,但我无法得到最终的解决方案。也许我可以根据您共享的 sidekiq.config 解决这个问题。谢谢。【参考方案2】:

我认为sidekiq api 可能会帮助您调试它。

首先,从 beanstalk 进入 rails 控制台:/var/app/current run RAILS_ENV=production bundle exec rails c 然后 require 'sidekiq/api'

如果您运行Sidekiq::Queue.new,它将返回您排队的作业或Sidekiq::RetrySet.new 用于计划重试的作业。如果您在上次部署之前有旧作业排队,那应该证实您对引用已删除目录的怀疑。

要安全关闭 Sidekiq,您需要向其发送 USR1 信号 在您的部署过程中尽可能早地发出 TERM 信号 尽可能。 USR1 告诉 Sidekiq 停止拉新工作并完成 当前的所有工作。 TERM 告诉 Sidekiq 在 N 秒内退出,其中 N 由 -t timeout 选项设置,默认为 8。使用 USR1+TERM 在 您的部署过程为您的工作提供了最大的时间 在退出之前完成。

您可以通过设置 sidekiq 工作人员只尝试一次然后死掉来避免这种情况。否则,您的工作人员将持续失败 25 次重试或 21 天。

class NonRetryableWorker
  include Sidekiq::Worker
  sidekiq_options retry: false
  # your perform method
end

您还可以设置sidekiq_options retry: 5 或任何其他整数来明确设置重试次数。

如果您使用 capistrano 进行部署,则可以使用 capistrano-sidekiq gem 管理部署之间的作业

【讨论】:

有趣,所以在一次部署中排队或失败意味着它将在下一次部署中失败,就像它以某种方式记住它的上下文一样?如果属实,这似乎是不可取的,想知道是否有解决方法。没有通过 sidekiq api 显示任何排队的作业 atm,但我肯定会进一步调查 实际上我们在 Sidekiq::RetrySet 中有一些。感觉这可能是问题 听起来就是这样。我使用 sidekiq 部署文档中解释问题的一些附加信息更新了答案。 因此,除非我误解了这里的理论,否则作业要么记住它们的失败上下文,并且您不能在另一个部署中运行从一个部署排队的作业(即not true)。或者 Sidekiq 没有通过 USR1/TERM 序列正确关闭,但是我们只会在部署期间看到此故障(事实并非如此,我在 10 分钟前才看到一个,而且我们已经好几天没有部署了)。 作业不记得失败的上下文,问题似乎与使用旧环境配置运行的部署序列有关。如果您运行 Sidekiq::RetrySet.new.map |x|,您会收到什么样的错误消息? x.item["error_message"] 【参考方案3】:

我无法运行您的sidekiq.conf 或0010_sidekiq.config(最接近您的配置)。我也不确定您第一次如何配置 sidekiq,也许您可​​以提供有关您的 .ebextensions 和配置的更多详细信息。当我尝试使用你的配置时,我得到which sidekiq line is error:

/var/log/eb-activity.log

...

  ++ which bundle
  + BUNDLE=/opt/rubies/ruby-2.2.2/bin/bundle
  ++ which sidekiq
  which: no sidekiq in (/opt/rubies/ruby-2.2.2/bin:/opt/elasticbeanstalk/lib/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin)
  + SIDEKIQ= (Executor::NonZeroExitStatus)


[2015-09-08T15:24:52.326Z] INFO  [4963]  - [Application update/AppDeployStage1/AppDeployPostHook/50_restart_sidekiq.sh] : Activity failed.
[2015-09-08T15:24:52.327Z] INFO  [4963]  - [Application update/AppDeployStage1/AppDeployPostHook] : Activity failed.
[2015-09-08T15:24:52.327Z] INFO  [4963]  - [Application update/AppDeployStage1] : Activity failed.
[2015-09-08T15:24:52.327Z] INFO  [4963]  - [Application update] : Completed activity. Result:
  Application update - Command CMD-AppDeploy failed

但是,我正在使用另一个.ebextensions:https://github.com/jolks/ebextensions(注意:不要忘记将RAILS_ENV 设置为您的EB 环境变量)。它运行正常。基本上,.ebextensions 会在您的应用刚刚部署后尝试重新启动 sidekiq。

【讨论】:

根据您的回复不确定该去哪里...我们的 sidekiq 配置在大多数情况下似乎都可以正常工作;看起来你没有运行 bundle 或其他东西,因为 which sidekiq 如果安装不应该失败并且我们没有这个问题。我们的RAILS_ENV 设置正确。 能否提供与sidekiq相关的.ebextensions 这就是this,你已经在引用它了。我们没有其他与 sidekiq 相关的配置文件 当你运行bundle install安装sidekiq?【参考方案4】:

我在你描述的场景中遇到了这个错误:

我们的一些后台工作人员未能停止部署,然后 capistrano 开始删除旧部署的目录。如果在旧(现已删除)目录之一中启动的工作人员仍然存在,那么您观察到的错误开始发生......

解决方案显然是确保在部署时正确终止您的旧进程......不幸的是我既不使用 EB 也不使用 Sidekiq 所以我不能帮您解决具体问题...

【讨论】:

嗯,很高兴知道这不是一个新问题:)。听起来这支持了我最初的猜测,现在来追查为什么这些进程没有被终止......

以上是关于Elastic Beanstalk 上的 Sidekiq 进程 - Errno::ENOENT:没有这样的文件或目录 - getcwd的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk 上的 Spring Boot 并记录到文件

Elastic Beanstalk 上的 SSL

如何避免 AWS Elastic Beanstalk 上的 TooManyApplicationVersion 异常?

如何避免 AWS Elastic Beanstalk 上的 TooManyApplicationVersion 异常?

无法连接到 Elastic Beanstalk 上的 ActionCable

AWS Elastic Beanstalk 上的 Wordpress