原版本

╭─sky@sky-linux /ihome/nginx/nginx-1.8
╰─➤  ./sbin/nginx -V
nginx version: nginx/1.8.0
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
configure arguments: --prefix=/ihome/nginx/nginx-1.8
╭─sky@sky-linux /ihome/nginx/nginx-1.8
╰─➤

╭─sky@sky-linux /ihome/nginx/nginx-1.8
╰─➤  ps aux | grep "[n]ginx"
root     22369  0.0  0.0  28464   556 ?        Ss   17:00   0:00 nginx: master process ./sbin/nginx
nobody   22370  0.0  0.0  28888  2684 ?        S    17:00   0:00 nginx: worker process
╭─sky@sky-linux /ihome/nginx/nginx-1.8
╰─➤

编译新版本

./configure --prefix=旧版本的nginx目录
make -j 8

将旧版本的nginx二进制文件备份下
cp /旧版本nginx目录/sbin/nginx /旧版本ningx目录/sbin/nginx.old

将新编译好的nginx二进制文件复制到旧版本的nginx目录sbin下
cp /新版本编译目录/objs/nginx /旧版本nginx目录/sbin/nginx

平滑升级

切换pid

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  sudo kill -USR2 `cat logs/nginx.pid`
╭─sky@sky-linux

成功后,就可以看到

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  ll logs
total 44K
-rw-r--r-- 1 sky  sky  25K  1月 25 17:17 access.log
-rw-r--r-- 1 sky  sky  625  1月 25 17:16 error.log
-rw-r--r-- 1 root root   6  1月 25 17:16 nginx.pid
-rw-r--r-- 1 root root   6  1月 25 17:13 nginx.pid.oldbin
╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤

它生成了一个nginx.pid.oldbin

这时,可以看到有两个nginx进程了

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  ps aux | grep "[n]ginx"
root     25690  0.0  0.0  28464  2160 ?        Ss   17:13   0:00 nginx: master process ./sbin/nginx
nobody   25691  0.0  0.0  28888  2572 ?        S    17:13   0:00 nginx: worker process
root     26668  0.0  0.0  28468  3520 ?        S    17:16   0:00 nginx: master process ./sbin/nginx
nobody   26671  0.0  0.0  28880  2416 ?        S    17:16   0:00 nginx: worker process
╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤

新版本的nginx也已经启动了.

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  ./sbin/nginx -V
nginx version: nginx/1.9.9
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
configure arguments: --prefix=/ihome/nginx/nginx-current
╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤

停止旧nginx的worker

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  sudo kill -WINCH `cat logs/nginx.pid.oldbin`
╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤

停止旧nginx的master

╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤  sudo kill -QUIT `cat logs/nginx.pid.oldbin`
╭─sky@sky-linux /ihome/nginx/nginx-current
╰─➤

这样子就OK了.

脚本

放在 Nginx 的根目录下, 修改下 NEW_NGINX 参数再执行

#!/usr/bin/env bash
set -e

NEW_NGINX="/path/to/new/nginx"
OLD_NGINX="sbin/nginx"

echo "backup..."
mv "${OLD_NGINX}" "${OLD_NGINX}.bak"
mv "${NEW_NGINX}" "${OLD_NGINX}"
echo "backup ok..."

echo "start new nginx..."
sudo kill -USR2 `cat logs/nginx.pid`
ps aux | grep nginx
echo "start new nginx ok..."

echo "shutdown old worker and master..."
sudo kill -WINCH `cat logs/nginx.pid.oldbin`
sleep 2
sudo kill -QUIT `cat logs/nginx.pid.oldbin`
echo "shutdown old worker and master ok..."

echo "Success.... ^_^"