升级原理
(1)在不停掉老进程的情况下,启动新进程。
(2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
(3)新进程接受新请求。
(4)老进程处理完所有请求,关闭所有连接后,停止。
编译安装顺便升级,和之前软件升级不一样,之前需要先停掉,卸载。现在我们在不影响客户端连接的情况下给它升级。
升级操作
查看现有的 nginx 编译参数
[root@www ~]# /usr/local/nginx/sbin/nginx -V
这是刚开始安装时,configure后面跟的东西,将来到了公司,不可能像现在装了旧版本,立马装新版本,可能是一两年之后才需要做升级,第一次安装的时候用的哪些选项,哪些参数,一年之后可能就忘了,可能文档都找不到了,所以这个-V还是能用的到的。
-V 查看详细安装信息
-v 单独查看版本信息
为什么要查这个?
在升级的时候,尽量保证新安装的版本,要包含旧版本的参数。不能原来有的功能,装了新版本没有了。
按照原来的编译参数安装 nginx 的方法进行安装,只需要到 make,千万不要 make install 。如果make install 会将原来的配置文件覆盖(还有另外的方法,直接把新版安装到另一个目录,然后拷贝新版启动文件到旧版目录)如果真被覆盖,也可以解决,因为配置文件不可能不备份。
安装新版本nginx-1.23.1
解压到nginx23目录下
[root@www ~]# tar xvzf nginx-1.23.1.tar.gz -C /nginx23/
看一下现在的版本
[root@www ~]# /usr/local/nginx/sbin/nginx -v
查一下进程
ps aux | grep nginx
新安装的软件,装在这里,先不要覆盖原来的安装
[root@www nginx-1.23.1]# mkdir /usr/local/nginx23
用户可以用同一个用户,sbin目录也得改。 回车执行
./configure --prefix=/usr/local/nginx23 --group=nginx --user=nginx --sbin-path=/usr/local/nginx23/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --with-http_image_filter_module
[root@www nginx-1.23.1]# make
【注意】make完毕之后,千万不要 make install。
有个提示。objs,它在当前目录下,cd到objs里面有nginx,这就是新安装的nginx
拷贝之前,先把原来/usr/local/nginx/sbin/nginx移动一下,就是做个备份,万一新升级的不行。
[root@www objs]# mv /usr/local/nginx/sbin/nginx /(做个备份)
把新安装的nginx拷贝到原来nginx所在的目录下
[root@www objs]# cp nginx /usr/local/nginx/sbin/
测试新版本的nginx是否正常
[root@www objs]# /usr/local/nginx/sbin/nginx -t
开始升级
怎么升级?
系统里面有一个信号,叫做WINCH和USR2。
方法一、
要找到pid文件,里面记录了nginx的id号。 这个主进程就是它的id号。就不用去看pid文件了。
[root@www objs]# ps aux | grep nginx 找到主进程id号,发送信号。
[root@www objs]# kill -USR2 58272 给nginx发送平滑迁移信号
这个不是杀死信号,这是告诉主进程,要做平滑升级,它会生成两个全新的进程。
[root@www objs]# kill -WINCH 58272 从容关闭旧的Nginx进程
[root@www objs]# kill -QUIT 58272 结束工作进程,完成此次升级
验证Nginx是否升级成功
之前是1.18.0,现在是1.23.1。升级成功
方法二、
若不清楚pid路径,请查看nginx配置文件
kill -USR2 `cat /var/run/nginx.pid`
查看nginx pid,会出现一个nginx.pid.oldbin
ll /var/run/nginx.pid*
cat /var/run/nginx.pid 是记录的新的nginx的进程
cat /var/run/nginx.pid.oldbin 记录的是旧的
这个就叫平滑升级,或者在线升级,热升级。现有的客户端是不会被断开连接的,比如旧的进程,被客户端连接着,按以前的做法直接把服务关掉了,那客户端,肯定都断开连接了。现在旧的进程没有被干掉,但是从现在开始再有新的客户端,连接进来,它也不会去连旧的进程,它会直接连新的进程。
旧的进程怎么办,什么时候关掉呢?
我们会给旧的进程发送一个优雅关闭的信号,优雅关闭,指没有被客户端连接的时候再关闭掉,反正新的客户端,都会连接在新的进程,旧的进程都是旧的客户端连接,那就发送一个优雅关闭的信号。
关闭信号是干什么的?
等待旧的进程被客户端断开连接,就是没有客户端访问了我再关掉。
优雅关闭/从容关闭旧的Nginx进程
kill -WINCH `cat /var/run/nginx.pid.oldbin`
结束工作进程,完成此次升级
kill -QUIT `cat /var/run/nginx.pid.oldbin`
【注意】正常在生产环境,为了给客户一个完美的体验,最好先不要敲QUIT,因为它很可能直接把这个进程给干掉。
验证Nginx是否升级成功
[root@www objs]# /usr/local/nginx/sbin/nginx -v
之前是1.18.0,现在是1.23.1。升级成功
从始至终,客户端是感觉不到的,就算强制把旧的进程关闭掉,客户端那里无非就是刷新一下。
这样就很方便地实现了平滑升级。
一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块
主进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待工作进程结束后再退出
- KILL: 强制终止进程
- HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
- USR1: 重新打开日志文件
- USR2: 启动新的主进程,实现热升级
- WINCH: 逐步关闭工作进程
工作进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待请求处理结束后再退出
- USR1: 重新打开日志文件