好吧,这正在融化我的大脑。这可能与我不太了解 Upstart 的事实有关。提前抱歉这个长问题。
我正在尝试使用 Upstart 来管理 Rails 应用程序的 Unicorn 主进程。这是我目前的/etc/init/app.conf
:
description "app"
start on runlevel [2]
stop on runlevel [016]
console owner
# expect daemon
script
APP_ROOT=/home/deploy/app
PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH
$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1
end script
# respawn
这很好用——独角兽的起步很好。不好的是,检测到的 PID 不是 Unicorn master 的,而是一个sh
进程的。这本身也不是那么糟糕——如果我没有使用自动独角兽零停机部署策略的话。因为在我发送给我的独角兽主人后不久-USR2
,一个新的主人产生了,而旧的主人死了……这个sh
过程也是如此。所以 Upstart 认为我的工作已经死了,如果我愿意,我不能再重新启动它restart
或停止它。stop
我玩过配置文件,尝试将 -D 添加到 Unicorn 行(像这样$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production -D
:)以守护 Unicorn,我添加了该expect daemon
行,但这也不起作用。我也试过expect fork
了。所有这些事情的各种组合都可能导致start
并stop
挂起,然后 Upstart 对工作的状态感到非常困惑。然后我必须重新启动机器来修复它。
我认为 Upstart 在检测 Unicorn 何时/是否分叉时遇到问题,因为我在脚本ruby-local-exec
中使用了 rbenv + shebang 。$APP_ROOT/bin/unicorn
这里是:
#!/usr/bin/env ruby-local-exec
#
# This file was generated by Bundler.
#
# The application 'unicorn' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('unicorn', 'unicorn')
此外,ruby-local-exec
脚本如下所示:
#!/usr/bin/env bash
#
# `ruby-local-exec` is a drop-in replacement for the standard Ruby
# shebang line:
#
# #!/usr/bin/env ruby-local-exec
#
# Use it for scripts inside a project with an `.rbenv-version`
# file. When you run the scripts, they'll use the project-specified
# Ruby version, regardless of what directory they're run from. Useful
# for e.g. running project tasks in cron scripts without needing to
# `cd` into the project first.
set -e
export RBENV_DIR="${1%/*}"
exec ruby "$@"
所以里面有一个exec
让我担心的地方。它启动了一个 Ruby 进程,它启动了 Unicorn,它可能会或可能不会守护自己,这一切都首先发生在一个sh
进程中......这让我严重怀疑 Upstart 跟踪所有这些废话的能力。
我想要做的甚至可能吗?据我了解,expect
Upstart 中的节只能被告知(通过daemon
或fork
)期望最多两个分叉。