Unicorn继续在部署+重启后使用旧代码

D-N*_*ice 8 capistrano unicorn

task :restart_unicorn, :except => { :no_release => true } do
  run "#{try_sudo} kill -s USR2 $(cat /var/www/app_name/shared/pids/unicorn.pid)"
end
Run Code Online (Sandbox Code Playgroud)

当我sudo kill -s USR2 $(cat /var/www/app_name/shared/pids/unicorn.pid)在服务器上执行操作时,会发生一个新的独角兽主人,并且旧的独角兽主人员已经(old)附加到其名称上.旧的永远不会被杀死,但即使我自己杀了它,新的独角兽实例仍然会在部署之前显示旧代码.新实例与旧实例具有相同的创建时间 - 就好像它只是被复制一样.如果我停止实例,并再次启动它,它可以工作,但我希望能够进行零停机时间部署.

任何帮助表示赞赏.

编辑

在追随最大的Ilya O.之后,我创建了一个执行此操作的capistrano任务:

old_pid = get_pid('/var/www/appname/shared/pids/unicorn.pid')
run "#{try_sudo} kill -s SIGUSR2 $(cat /var/www/appname/shared/pids/unicorn.pid)"
/var/www/app/current/tmp/pids/unicorn.pid)"
run "#{try_sudo} kill -s SIGWINCH #{old_pid}"
Run Code Online (Sandbox Code Playgroud)

这会在pid上运行SIGUSR2,并杀死旧的独角兽进程.问题是我的所有应用程序服务器永远不会更新到我最近部署的代码,这个任务似乎只是将旧的独角兽环境复制到一个新进程中.如果我简单地杀死主进程然后再次启动独角兽,它可以正常工作,但随后有一分钟左右的请求被删除.

Ily*_* O. 6

preload_app在Unicorn配置中设置为true吗?如果是这样,您需要在新进程启动并运行后将SIGUSR2然后SIGQUIT发送到原始主进程.

可能还会发生的是原始主进程已经死亡,但是孩子们仍在处理请求.您可以尝试发送SIGUSR2,并在生成新的主进程后,发送SIGWINCH(到旧主服务器)以终止旧的独角兽子进程,然后在旧的主进程上发送SIGQUIT.您现在应该只有"新"的独角兽进程来处理请求.

编辑:尝试使用SIGQUIT而不是SIGWINCH.我认为旧的流程可能会在SIGWINCH之后产生工人.