发送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,那么从客户端的角度来看,所有的请求都能很快地得到响应:我可以重载浏览器,并且每个请求都能迅速得到填充,除了看到我的代码更改之外,没有任何其他指示新的主控节点何时接管请求。但是,旧的主控节点现在仍然存在,直到我手动发送QUIT为止。
据我所知,一旦工作者完成加载并准备好为客户端提供服务,就没有回调函数可用。这确实是我正在寻找的回调函数。我始终可以在Rails本身中创建一个初始化程序,查找旧的主控节点并将其关闭,但只是想想就让我心痛。
一定有方法!