Nginx 平滑升级或添加模块小记

PHPABC Nginx 887 次浏览 , , 没有评论

先查看下当前Nginx 的版本和编译参数

linux-phpabc:# /usr/local/sbin/nginx -V
nginx version: nginx/1.0.11
built by gcc 4.1.2 20070115 (prerelease) (SUSE Linux)
configure arguments: --prefix=/usr/local/nginx

然后开始平滑升级和添加模块

一、用make upgrade 完成平滑升级

1.按需编译新版本的nginx
根据需求编译新版本的nginx,在执行到make时就打住,不要make install!

#下载1.5.7版本,并解压
cd /usr/local/src
wget http://nginx.org/download/nginx-1.6.0.tar.gz
tar zxvf nginx-1.6.0.tar.gz
cd nginx-1.6.0
 
#根据实际需要新增的模块,先准备所需文件(其实只需要解压即可,全部安装,后面编译就可以不指定路径了):
#1. 安装pcre:
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.34.tar.gz 
tar -zxvf pcre-8.34.tar.gz
cd pcre-8.34
./configure && make && make install
 
#2. 安装zlib:
cd /usr/local/src
wget http://zlib.net/zlib-1.2.8.tar.gz
tar -zxvf zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure && make && make install
 
#3. 安装openssl:
cd /usr/local/src
wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
tar -zxvf openssl-1.0.1c.tar.gz
cd openssl-1.0.1c
./configure && make && make install
 
#加上所需参数开始编译:
./configure --user=www --group=www \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-openssl=/usr/local/src/openssl-1.0.1c \ #对应openssl源码解压后的路径,下同(pcre,zlib)
--with-http_stub_status_module \
--with-pcre \
--with-pcre=/usr/local/src/pcre-8.21 \
--with-zlib=/usr/local/src/zlib-1.2.8
 
#执行make编译,但是不要执行make install
 
make

2、重命名nginx旧版本二进制文件,即sbin目录下的nginx(期间nginx并不会停止服务!):

linux-phpabc:/usr/local/src/nginx-1.6.0 # mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old

3、然后拷贝一份新编译的二进制文件:

linux-phpabc:/usr/local/src/nginx-1.6.0 # cp objs/nginx /usr/local/nginx/sbin/

4、在源码目录执行make upgrade开始升级:

linux-phpabc:/usr/local/src/nginx-1.6.0 # make upgrade
 
#下面是make upgrade命令的打印信息:
/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
 
#最后确认一下nginx进程,可以发现有2个主进程,并且有正在关闭的进程(shutting down):
linux-gz215:/usr/local/src/nginx-1.6.0 # ps aux | grep nginx
root 969 0.0 0.3 8260 1844 ? Ss Dec09 0:01 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
www 4196 0.1 2.5 19112 12872 ? S 14:52 0:00 nginx: worker process is shutting down
www 4260 0.1 2.5 19112 12872 ? S 14:52 0:00 nginx: worker process is shutting down
www 4257 0.1 2.5 19112 12872 ? S 14:52 0:00 nginx: worker process is shutting down
root 4663 0.0 0.3 5488 1900 ? S 14:58 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
 
#过一段时间后,再次确认nginx进程,可以发现老进程已自动退出了(存在一段时间是因为旧进程还有未结束的服务)
root 969 0.0 0.3 8260 1844 ? Ss Dec09 0:01 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
www       4665  0.1  2.4  16508 12444 ?        S    14:58   0:01 nginx: worker process

最后确认一下:

linux-phpabc:~ # /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.6.0
built by gcc 4.1.2 20070115 (prerelease) (SUSE Linux)
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.1c --with-http_stub_status_module --with-pcre --with-pcre=/usr/local/src/pcre-8.21 --with-zlib=/usr/local/src/zlib-1.2.8

二、纯手动平滑升级

纯手动模式,指的是在最后做迁移的时候,全部使用手动命令来搞定,避免编译可能存在不一致的参数啥的。
实际上,在make之后,我们可以查看nginx源码目录下的Makefile内容如下:

default:        build
 
clean:
        rm -rf Makefile objs
 
build:
        $(MAKE) -f objs/Makefile
        $(MAKE) -f objs/Makefile manpage
 
install:
        $(MAKE) -f objs/Makefile install
 
upgrade:
        /usr/local/nginx/sbin/nginx -t
 
        kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
        sleep 1
        test -f /usr/local/nginx/logs/nginx.pid.oldbin
 
        kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

所以,说白了纯手动就是执行upgrade标签下的命令行而已,实际上只要确认Makefile下的命令路径都是正确的,用命令自动迁移是没有任何问题的。
总是有人会不放心的,喜欢手动一步一步的搞定,我也来整理下纯手动步骤:

①~③和之前的一样,按常规步骤先编译nginx,不过只执行到make就打住,然后将旧的sbin下的nginx文件移走,再将编译得到的objs目录下的nginx文件放到原来的sbin目录。

4、测试新版本的nginx是否正常:

[root@Mars_Server nginx-1.6.0]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok #OK,没有问题! nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

5、给旧nginx发送平滑迁移信号(若不清楚pid路径就用可用命令(2)):
#可用命令(1):

kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` #可用命令(2): kill -USR2 `ps aux | grep "nginx: master process" | grep -v grep | awk '{print $2}'`
 
#可用命令(2):
kill -USR2 `ps aux | grep "nginx: master process" | grep -v grep | awk '{print $2}'`

Ps:后面其实就是旧nginx的pid,所以先用ps aux找到正在运行的nginx主进程pid,再执行 kill -USR2 PID值亦可。
6、等待旧版本Nginx的pid变为oldbin(执行如下命令查看是否生成)

test -f /usr/local/nginx/logs/nginx.pid.oldbin && echo OK!

7、 从容关闭旧版本的Nginx进程

kill –WINCH `cat /usr/local/nginx/log/nginx.oldbin`

此时,旧的工作进程就都会慢慢随着任务执行完毕而退出,新版的Nginx的工作进程会逐渐取代旧版工作进程。

8、此时,不重载配置启动旧工作进程(个人感觉是为了将任务完全切换到新的nginx上)

kill –HUP `cat /url/local/nginx/log/nginx.oldbin`

9、结束工作进程,完成此次升级操作:

kill –QUIT `cat /usr/local/nginx/log/nginx.oldbin`

10、最后,验证nginx是否升级成功:

linux-phpabc:~ # /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.6.0 #没问题 built by gcc 4.1.2 20070115 (prerelease) (SUSE Linux) TLS SNI support enabled configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.1c --with-http_stub_status_module --with-pcre --with-pcre=/usr/local/src/pcre-8.21 --with-zlib=/usr/local/src/zlib-1.2.8

特意测试了下纯手动的做法,下面是我的操作记录,仅供参考:
为了验证平滑升级确实不影响在线业务,我特意在升级的时候,利用ab命令一直在发送请求:

ab -n1000000 -c10 http://phpabc.cn/

直到升级完成,使用ctrl +C 终止并查看ab结果,可以发现几十万次的请求全部成功,没有失败!证明平滑升级的可行性!可惜忘记了截图,感兴趣的童鞋可以自行测试下!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Go