nginx
nginx的版本更新快,新特性发展的蛮快的,而对于需要加入新特性或更新版本,我们并没有必要停机升级,这就是我们想要说的这不影响线上业务的情况下,如何平滑的升级nginx。
nginx 半自动化升级
首先必须明确我们这次升级是为了什么,更新版本,并且加入http_realip_module模块这个新功能,这个模块在7层代理的情况下,可以透传真正的客户ip,那我们先来看下线上nginx的版本信息:
1 | [root@localhost /usr/local/nginx/sbin]#./nginx -V |
2 | nginx version: nginx/1.9.12 |
3 | built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) |
4 | built with OpenSSL 1.0.1e-fips 11 Feb 2013 |
5 | TLS SNI support enabled |
6 | configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_sub_module |
线上nginx版本为1.9.12,官网上最新的稳定版本已经到了1.10.3,虽然并不建议线上版本一定要更新到最新,但既然执行了一次升级操作了,那我们就更新到最新的版本算了。
- 拷贝下nginx目录,以防万一,cp /usr/local/nginx /usr/local/nginx.bak
- 下载最新版本nginx-1.10.3.tar.gz
- 编译新版本的nginx
1
[root@localhost /data/nginx-1.10.3]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_sub_module --with-http_realip_module #编译并加入新特性
2
[root@localhost /data/nginx-1.10.3]#make #千万别make install,不然你就准备挨事故吧
3
[root@localhost /data/nginx-1.10.3]#cp objs/nginx /usr/local/nginx/sbin #将编译好的新的nginx二进制文件替换掉现在的nginx文件,这里可能会报nginx真正忙,我们可以强制替换
4
[root@localhost /data/nginx-1.10.3]#ps aux | grep nginx #我们可以先看下现在的nginx进程
5
[root@localhost ~/nginx/nginx-1.10.3]#ps aux | grep nginx
6
root 3687 0.0 0.0 112648 968 pts/1 S+ 05:47 0:00 grep --color=auto nginx
7
root 4980 0.0 0.0 48120 1696 ? Ss Feb13 0:00 nginx: master process ./n
8
...
9
[root@localhost ~/nginx/nginx-1.10.3]#cat Makefile #我们看下make生成的Makefile,主要看upgrade的内容
10
default: build
11
clean:
12
rm -rf Makefile objs
13
build:
14
$(MAKE) -f objs/Makefile
15
install:
16
$(MAKE) -f objs/Makefile install
17
upgrade:
18
/usr/local/nginx/sbin/nginx -t
19
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
20
sleep 1
21
test -f /usr/local/nginx/logs/nginx.pid.oldbin
22
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
23
[root@localhost ~/nginx/nginx-1.10.3]#ll /usr/local/nginx/logs/nginx.pid #做好确认工作,如果pid文件自己修改过,就修改Makefile的内容
24
[root@localhost ~/nginx/nginx-1.10.3]#make upgrade #nginx平滑升级
25
[root@localhost ~/nginx/nginx-1.10.3]#ps aux | grep nginx #看下新的nginx master进程是否已经起来了
26
[root@localhost /usr/local/nginx/sbin]#ps aux | grep nginx #好了新的nginx进程起来了
27
root 3755 0.0 0.0 45244 1116 ? Ss 05:55 0:00 nginx: master process ./nginx
28
www 3756 0.0 0.1 45688 1892 ? S 05:55 0:00 nginx: worker process
29
...
30
[root@localhost /usr/local/nginx/sbin]#./nginx -V #nginx升级完成
31
nginx version: nginx/1.10.3
32
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
33
built with OpenSSL 1.0.1e-fips 11 Feb 2013
34
TLS SNI support enabled
35
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_sub_module --with-http_realip_module
36
[root@localhost /usr/local/nginx/sbin]#./nginx -t #nginx测试下
37
[root@localhost /usr/local/nginx/sbin]#./nginx -s reload
好了,这就是整个nginx升级的过程,整个升级过程,线上就没断过,这被称为nginx半自动化平滑升级,也是nginx官方建议的方式,但总有万一,如果这个方式升级失败我们只能手动升级。
nginx 手动升级
其实整个手动过程就是将Makefile的过程手工执行。
1 | 给旧的nginx发送平滑迁移信号 |
2 | [root@localhost ~]#kill -USR2 `cat /usr/local/nginx/log/nginx.pid` |
3 | 或者 |
4 | [root@localhost ~]#kill -USR2 `ps aux | grep "nginx :master process"| grep -v grep | awk '{print $2}'` |
5 | 等待旧版本的nginx的pid变成oldbin |
6 | [root@localhost ~]#test -f /usr/local/nginx/log/nginx.pid.oldbin && echo 'ok' |
7 | 从容关闭旧版本的nginx的进程 |
8 | [root@localhost ~]#kill -WINCH `cat /usr/local/nginx/log/nginx.pid.oldbin` |
9 | 此时,旧的工作进程就会慢慢随着任务执行完毕儿退出,新的nginx的工作进程会逐渐取代旧版本的进程 |
10 | 此时,不重载配置启动旧的工作进程(为了完全把任务给新的nginx上) |
11 | [root@localhost ~]#kill -HUP `cat /usr/local/nginx/log/nginx.oldbin` |
12 | 结束工作进程,完成此次升级操作 |
13 | [root@localhost ~]#kill -QUIT `cat /usr/local/nginx/log/nginx.oldbin` |
14 | 最后验证nginx是否升级成功 |
15 | [root@localhost ~]#./nginx -V |
手动升级步骤多,如果出错,则会影响线上业务,所以能半自动化升级尽量自动升级,只有在自动升级失败才执行手动升级。