目前我的用法是:
$ cat cat tmp/pids/unicorn.pid
25361
$ kill -USR2 25361
但是,我发现这样做了以后,进程列表会出现两份,新的是启动上来了,但是老的进程依然存在,除非我再 kill -QUIT 25361 这个进程
我这个方法不知道对不对
需要改下配置:
# 如果用USR2信号重启服务,必须要配置这一步, 用来退出老的master
# 请参考:
# http://unicorn.bogomips.org/SIGNALS.html
# https://github.com/blog/517-unicorn
before_fork do |server, worker|
old_pid = "#{shared_path}/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
puts "Send 'QUIT' signal to unicorn error!"
end
end
end
@huacnlee 其实这个问题在我的本机开发中我也遇到了,你的做法是对的,先用 USR2,当新的 master process 启动好了以后,需要给原有的 master process 发送一个 QUIT singal,对于这个流程官方网站解释的非常清楚: http://unicorn.bogomips.org/SIGNALS.html (Procedure to replace a running unicorn executable)
关于自动化这个流程,可以参见 Unicorn 的官方 example: https://github.com/defunkt/unicorn/blob/master/examples/init.sh
btw: 我用
pstree -s unicorn
来查看 unicorn 的新老进程的状态
_pid=cat tmp/pids/unicorn.pid
; sudo kill -USR2 $_pid; sudo kill -QUIT $_pid; ps -ef | grep unicorn | grep master
#4 楼 @huacnlee 在官方提供的 init.sh 脚步中,是这样判断的:
upgrade)
if sig USR2 && sleep 2 && 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
;;
不过我还没有在本机测试过,我现在仍然采用手杀,晚上找个时间我试试看。
多服务器的话挨个杀了重启也无缝...
蛋疼的"内存占用也平滑"法: 让发减员信号给老 master, 起进程数稍少的新 master, 起来后杀老 master, 然后发增员信号给新 master
谁之前用得熟悉的,看看 ruby-china 的 unicorn.rb 写得对不对 https://github.com/huacnlee/ruby-china/blob/master/config/unicorn.rb
unicorn.rb : 为什么既 listen port 又 listen socket, 其中一个可以去掉吧,和 nginx 的配置对应就可以了
timeout 设短一点,假如 6 个人同时点了用 google 登录,每个进程都在 wait google response, 就要死 120 秒了
@huacnlee @lgn21st sorry,原来是这样的
before_fork do |server, worker|
old_pid = "#{Rails.root}/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
puts "Send 'QUIT' signal to unicorn error!"
end
end
end