Nginx作为Web服务器的后起之秀,因其显著的性能,越来越受到企业的青睐,众多大型网站都从Apache迁移到Nginx,淘宝更是在其基础上发起了Tengine开源项目,可见Nginx在Web服务器中地位之重。
Web服务器作为用户请求后端服务器的入口,不单只负责建立连接,处理请求,还承担着“守门卫”的安全职责。从安全角度来说,Nginx本身的安全性十分重要,因此必须时刻关注Nginx的安全升级补丁。
本篇文章主要介绍“如何在不影响用户访问的情况下平滑升级Nginx”。
下载nginx最新稳定版, 这里以0.7升级到1.4.1为例: [下载地址]
$ wget "http://nginx.org/download/nginx-1.4.1.tar.gz"
$ tar zxvf nginx-1.4.1.tar.gz #解压
查看当前已安装的nginx版本的编译参数(configure arguments):
$ nginx -V
nginx version: nginx/0.7.67
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log
--http-client-body-temp-path=/var/lib/nginx/body
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi
--http-log-path=/var/log/nginx/access.log
--http-proxy-temp-path=/var/lib/nginx/proxy
--lock-path=/var/lock/nginx.lock
--pid-path=/var/run/nginx.pid
--with-debug --with-http_dav_module --with-http_flv_module
--with-http_geoip_module --with-http_gzip_static_module
--with-http_realip_module --with-http_stub_status_module
--with-http_ssl_module --with-http_sub_module
--with-ipv6 --with-mail --with-mail_ssl_module
--add-module=/build/buildd/nginx-0.7.67/modules/nginx-upstream-fair
根据旧版本的编译参数重新编译新版本:
$ cd nginx-1.4.1
$ ./configure --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log
--http-client-body-temp-path=/var/lib/nginx/body
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi
--http-log-path=/var/log/nginx/access.log
--http-proxy-temp-path=/var/lib/nginx/proxy
--lock-path=/var/lock/nginx.lock
--pid-path=/var/run/nginx.pid
--with-debug --with-http_dav_module --with-http_flv_module
--with-http_geoip_module --with-http_gzip_static_module
--with-http_realip_module --with-http_stub_status_module
--with-http_ssl_module --with-http_sub_module
--with-ipv6 --with-mail --with-mail_ssl_module
$ make #编译,编译后这里不要执行make install,后面手动安装
P.S: 编译过程中可能会出现缺少xxx libary的情况, 可参考这遍文章来安装缺少的lib。
编译完成后,替换 nginx 二进制文件。
$ sudo mv /usr/sbin/nginx /usr/sbin/nginx.old #备份旧文件, 具体路径可能有所不同, 可以通过命令which nginx查看)
$ sudo cp objs/nginx /usr/sbin/nginx #替换为新编译的nginx
$ sudo /usr/sbin/nginx -t #测试是否正常
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: [emerg] mkdir() "/usr/local/nginx/uwsgi_temp" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed
提示/usr/local/nginx目录不存在,创建该目录:
$ sudo mkdir /usr/local/nginx
再次测试,一切正常:
$ sudo /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
启动新进程,关闭旧进程:
$ sudo kill -USR2 `cat /var/run/nginx.pid` #pid的文件路径可以参考第一步 nginx -V 的pid-path
执行完上一步后,nginx会把 nginx.pid 备份成 nginx.pid.oldbin,并启动新的nginx进程接收用户请求。
平滑关闭旧进程:
$ sudo kill -QUIT `cat /var/run/nginx.pid.oldbin`
升级完成:
$ nginx -V
nginx version: nginx/1.4.1
built by gcc 4.4.7 (Ubuntu/Linaro 4.4.7-1ubuntu2)
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-ipv6 --with-mail --with-mail_ssl_module
建议在整个升级过程中,运行一个脚本不断访问升级的网站,检测是否会出现服务中断的现象。
#!/bin/bash
while [ 0 ]
do
curl -I 'http://localhost:80/'
sleep 1
done
附其他参考资料:
http://blog.sina.com.cn/s/blog_537977e50100i1hz.html
http://weizhifeng.net/nginx-signal-processing-and-upgrade.html
http://www.vpsee.com/2011/03/install-nginx-with-geoip-module-for-country-targeting/
http://blog.linuxphp.org/archives/1430/