使用USR2重新启动Unicorn - 退出旧主服务器

时间:2011-04-26 17:32:50

标签: ruby-on-rails ruby unicorn

因此,将USR2发送到Unicorn非常棒 - 它会启动一个带有新代码副本的新主人,并自动获取任何更改。甜。我的问题是:我如何阻止老主人?显而易见的方式是在before_fork中:

before_fork do |server,worker|
  old_pid = '/var/www/current/tmp/pids/unicorn.pid.oldbin'
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

问题在于,一旦新的主人(和新工人)产生,他们就会杀死旧的主人。因此,对网站的任何请求都只是坐在那里等待新工作人员启动,通常在整个Rails堆栈加载时持续几秒钟。

如果我删除了我的before_fork一切正常,我希望(从客户的角度来看):我可以整天重新加载我的浏览器,每个请求都快速填写,没有迹象表明新主人何时接管(除了看到我的代码更改现在出现了)。但是,旧的主人现在一直挂着,直到我手动发送一个退出。

据我所知,一旦工人完成装载并准备为客户服务,就没有回调。这真的是我正在寻找的回调。我总是可以在Rails中创建一个初始化程序,它可以查找一个老主人并杀死它,但这只会让我的心受到伤害。

一定有办法!

3 个答案:

答案 0 :(得分:16)

我部分解决了这个问题:我看到的行为是由于没有使用preload_app true造成的。如果你有这个设置,那么整个应用程序由主人加载,工人很快就会产生。因此,如果第一个工人此时杀死了老主人,那就没关系,因为所说的工人可以立即开始提出请求!

如果你不能使用preload_app true那么你最好的选择可能就是将那个旧的pid-quit行为转移到Rails初始化程序中,这样第一个启动你的应用程序的工作者可以在Rails中杀死旧的主人已经启动并准备好处理请求。

答案 1 :(得分:8)

如果preload_appfalse,似乎向Unicorn主机发送HUP信号是更好的选择。

来自http://unicorn.bogomips.org/SIGNALS.html

  

HUP - 重新加载配置文件和   优雅地重启所有工人。如果   “preload_app”指令是假的(   默认),然后工人也会选择   任何应用程序代码更改时   重新启动。

答案 2 :(得分:3)

以下是我在before_fork块中的内容:

  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end

要重新启动我的独角兽,我有一个bash脚本,它有一个这样的方法:

if sig USR2 && sig 0 && oldsig QUIT
then
    n=$TIMEOUT
    while test -s $old_pid && test $n -ge 0
    do
        printf '.' && sleep 1 && n=$(( $n - 1 ))
    done
    echo

    if test $n -lt 0 && test -s $old_pid
    then
        echo >&2 "$old_pid still exists after $TIMEOUT seconds"
        exit 1
    fi
    exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
$CMD
;;

bash脚本发送一个USR2信号,该信号会分叉新的独角兽并创建旧的pid。然后它使用旧的pid向旧的独角兽发送QUIT信号。

这个过程非常有效,取自Where Unicorns go to die: Watching unicorn workers with monit,这是一个很好的资源。