ruby-on-rails – 使用Upstart管理Unicorn w / rbenv bundler binstubs w / ruby​​-local-exec shebang

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 使用Upstart管理Unicorn w / rbenv bundler binstubs w / ruby​​-local-exec shebang前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
好吧,这正在融化我的大脑.这可能与我不理解Upstart以及我应该理解的事实有关.提前抱歉,这个问题很长.

我正在尝试使用Upstart来管理Rails应用程序的Unicorn主进程.这是我目前的/etc/init/app.conf:

  1. description "app"
  2.  
  3. start on runlevel [2]
  4. stop on runlevel [016]
  5.  
  6. console owner
  7.  
  8. # expect daemon
  9.  
  10. script
  11. APP_ROOT=/home/deploy/app
  12. PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH
  13. $APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1
  14. end script
  15.  
  16. # respawn

这很好 – 独角兽开局很棒.不太好的是,检测到的PID不是独角兽大师,而是一个sh过程.这本身并不是那么糟糕 – 如果我没有使用自动化Unicorn零停机时间部署策略.因为在我将-USR2发送给我的独角兽大师之后不久,一个新的主人产生了,旧的主人死了…… sh过程也是如此.所以Upstart认为我的工作已经死了,我不能再重新启动它,或者如果我想要停止它就停止它.

我玩过配置文件,试图将-D添加到Unicorn线(如:$APP_ROOT / bin / unicorn -c $APP_ROOT / config / unicorn.rb -E production -D)来守护Unicorn,我添加了expect守护程序行,但这也没有用.我也试过期待fork.所有这些事情的各种组合可能导致开始和停止挂起,然后Upstart对工作状态感到困惑.然后我必须重新启动机器来修复它.

我认为Upstart在检测何时/如果Unicorn正在分叉时遇到问题,因为我在我的$APP_ROOT / bin / unicorn脚本中使用了rbenv ruby​​-local-exec shebang.这里是:

  1. #!/usr/bin/env ruby-local-exec
  2. #
  3. # This file was generated by Bundler.
  4. #
  5. # The application 'unicorn' is installed as part of a gem,and
  6. # this file is here to facilitate running it.
  7. #
  8.  
  9. require 'pathname'
  10. ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",Pathname.new(__FILE__).realpath)
  11.  
  12. require 'rubygems'
  13. require 'bundler/setup'
  14.  
  15. load Gem.bin_path('unicorn','unicorn')

另外,ruby-local-exec脚本如下所示:

  1. #!/usr/bin/env bash
  2. #
  3. # `ruby-local-exec` is a drop-in replacement for the standard Ruby
  4. # shebang line:
  5. #
  6. # #!/usr/bin/env ruby-local-exec
  7. #
  8. # Use it for scripts inside a project with an `.rbenv-version`
  9. # file. When you run the scripts,they'll use the project-specified
  10. # Ruby version,regardless of what directory they're run from. Useful
  11. # for e.g. running project tasks in cron scripts without needing to
  12. # `cd` into the project first.
  13.  
  14. set -e
  15. export RBENV_DIR="${1%/*}"
  16. exec ruby "$@"

所以那里有一位我担心的高管.它启动了一个Ruby进程,它启动了Unicorn,它可能会或可能不会自我守护,这一切都是从一个sh进程发生的……这让我严重怀疑Upstart跟踪所有这些废话的能力.

我甚至想做什么?根据我的理解,Upstart中的期望节只能被告知(通过守护进程或分叉)最多可以预期两个分叉.

解决方法

事实上,新贵的一个限制是它无法跟踪那些做独角兽正在做什么的守护进程……那就是fork / exec并退出他们的主进程.信不信由你,sshd在SIGHUP上做同样的事情,如果你看,/ etc / init / ssh.conf确保sshd在前台运行.这也是apache2仍然使用init.d脚本的一个原因.

当通过分叉然后退出接收SIGUSR1时,听起来像gunicorn实际上是守护自己.对于任何试图保持流程存活的流程管理者来说,这会让人感到困惑.

我想你有两个选择. 1只是在你需要时不使用SIGUSR1并停止/启动gunicorn.

另一种选择是不使用upstart的pid跟踪,只需这样做:

  1. start on ..
  2. stop on ..
  3.  
  4. pre-start exec gunicorn -D --pid-file=/run/gunicorn.pid
  5. post-stop exec kill `cat /run/gunicorn.pid`

不像pid跟踪那样性感,但至少你不必写一个完整的init.d脚本.

(顺便说一句,这与shebangs / execs无关.这两件事就像运行常规可执行文件一样,因此它们不会产生任何额外的分支).

猜你在找的Ruby相关文章