Elastic Beanstalk 上的 Sidekiq 进程 - Errno::ENOENT: 没有这样的文件或目录 - getcwd
Sidekiq process on Elastic Beanstalk - Errno::ENOENT: No such file or directory - getcwd
我们在 Elastic Beanstalk 管理的 EC2 实例上使用 rest-client to send external API requests on Sidekiq workers that spin up as a process。
在 Dir.home
失败时,rest-client 在后台使用 netrc, and 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;任何指导将不胜感激。
我运行完全按照你描述的场景进入这个错误:
我们的一些后台工作人员未能停止部署,然后 capist运行o 开始删除旧部署的目录。如果在旧(现已删除)目录之一中启动的工作人员仍然存在,那么您观察到的错误就会开始发生...
解决方案显然是确保您的旧进程在部署时正确终止...不幸的是我既不使用 EB 也不使用 Sidekiq 所以我无法帮助您解决具体问题...
我不能 运行 你的 sidekiq.conf nor 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 api 可能会帮助您调试它。
首先,从 beantalk 进入 rails 控制台:/var/app/current
运行 RAILS_ENV=production bundle exec rails c
然后 require 'sidekiq/api'
如果您 运行 Sidekiq::Queue.new
它将 return 您排队的作业或 Sidekiq::RetrySet.new
计划重试的作业。如果您在上次部署之前将旧作业排入队列,那应该可以证实您对引用已删除目录的怀疑。
To safely shut down Sidekiq, you need to send it the USR1 signal as
early as possible in your deploy process and the TERM signal as late
as possible. USR1 tells Sidekiq to stop pulling new work and finish
all current work. TERM tells Sidekiq to exit within N seconds, where N
is set by the -t timeout option and defaults to 8. Using USR1+TERM in
your deploy process gives your jobs the maximum amount of time to
finish before exiting.
您可以通过设置您的 sidekiq worker 只尝试一次然后死掉来避免这种情况。否则,您的工人将在 25 次重试或 21 天内一直失败。
class NonRetryableWorker
include Sidekiq::Worker
sidekiq_options retry: false
# your perform method
end
您还可以设置 sidekiq_options retry: 5
或任何其他整数来显式设置重试次数。
如果您使用 capistrano 进行部署,则可以使用 capistrano-sidekiq gem
管理部署之间的作业
正如问题和一些答案所预示的那样,这是一个避免终止的流氓进程,在这种情况下是由于我们早期部署之一的粗心配置更改。我们的第30行sidekiq.config控制进程数,我们从2降到1但是改完后没有手动从服务器上移除第二个进程
这个故事的寓意是,Sidekiq 进程 不仅 容易受到意外行为的影响 在 部署期间。即使没有 stopped/started 跨多个部署,我们的错误进程也很高兴地完成了工作,但是任何依赖 Dir.pwd
并且可能需要 ENV
数据的任何其他脚本都会失败 天 在稳定部署之后,如果 运行 在持久进程上。
如果您看到此类故障,绝对肯定您没有运行之前部署的意外进程。这意味着要确保它们在部署期间被正确终止 ,但还要确保您没有从以前的部署中遗留的东西。
我们在 Elastic Beanstalk 管理的 EC2 实例上使用 rest-client to send external API requests on Sidekiq workers that spin up as a process。
在 Dir.home
失败时,rest-client 在后台使用 netrc, and 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;任何指导将不胜感激。
我运行完全按照你描述的场景进入这个错误:
我们的一些后台工作人员未能停止部署,然后 capist运行o 开始删除旧部署的目录。如果在旧(现已删除)目录之一中启动的工作人员仍然存在,那么您观察到的错误就会开始发生...
解决方案显然是确保您的旧进程在部署时正确终止...不幸的是我既不使用 EB 也不使用 Sidekiq 所以我无法帮助您解决具体问题...
我不能 运行 你的 sidekiq.conf nor 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 api 可能会帮助您调试它。
首先,从 beantalk 进入 rails 控制台:/var/app/current
运行 RAILS_ENV=production bundle exec rails c
然后 require 'sidekiq/api'
如果您 运行 Sidekiq::Queue.new
它将 return 您排队的作业或 Sidekiq::RetrySet.new
计划重试的作业。如果您在上次部署之前将旧作业排入队列,那应该可以证实您对引用已删除目录的怀疑。
To safely shut down Sidekiq, you need to send it the USR1 signal as early as possible in your deploy process and the TERM signal as late as possible. USR1 tells Sidekiq to stop pulling new work and finish all current work. TERM tells Sidekiq to exit within N seconds, where N is set by the -t timeout option and defaults to 8. Using USR1+TERM in your deploy process gives your jobs the maximum amount of time to finish before exiting.
您可以通过设置您的 sidekiq worker 只尝试一次然后死掉来避免这种情况。否则,您的工人将在 25 次重试或 21 天内一直失败。
class NonRetryableWorker
include Sidekiq::Worker
sidekiq_options retry: false
# your perform method
end
您还可以设置 sidekiq_options retry: 5
或任何其他整数来显式设置重试次数。
如果您使用 capistrano 进行部署,则可以使用 capistrano-sidekiq gem
管理部署之间的作业正如问题和一些答案所预示的那样,这是一个避免终止的流氓进程,在这种情况下是由于我们早期部署之一的粗心配置更改。我们的第30行sidekiq.config控制进程数,我们从2降到1但是改完后没有手动从服务器上移除第二个进程
这个故事的寓意是,Sidekiq 进程 不仅 容易受到意外行为的影响 在 部署期间。即使没有 stopped/started 跨多个部署,我们的错误进程也很高兴地完成了工作,但是任何依赖 Dir.pwd
并且可能需要 ENV
数据的任何其他脚本都会失败 天 在稳定部署之后,如果 运行 在持久进程上。
如果您看到此类故障,绝对肯定您没有运行之前部署的意外进程。这意味着要确保它们在部署期间被正确终止