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 并记录到文件
如何避免 AWS Elastic Beanstalk 上的 TooManyApplicationVersion 异常?
如何避免 AWS Elastic Beanstalk 上的 TooManyApplicationVersion 异常?