nginx升級與回退

馬哥教育發表於2020-10-11

nginx1.16.1的部署安裝我參考的這個部落格https://www.cnblogs.com/FengGeBlog/p/13534156.html。先看下這個文章,然後一會我們對這個進行版本升級

注意:下文將1.16.1版本成為舊版本nginx,1.18.0成為新版本nginx

1、先確認舊的nginx程式是已經存在的

舊版本nginx啟動程式

[root@master2 nginx]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1496 ?        Ss   11:42   0:00 nginx: master process sbin/nginx
nobody   17441  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17442  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17443  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17444  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17445  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process

舊版本的nginx我已經啟動了,設定5個worker程式。

2、開始編譯安裝新版本1.18.0的nginx

編譯的步驟如下所示:

wget http://nginx.org/download/nginx-1.18.0.tar.gz
mv nginx-1.18.0.tar.gz /usr/local
cd /usr/local
tar xf nginx-1.18.0.tar.gz

先獲取舊版本nginx編譯的選項

[root@master2 nginx]# sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_image_filter_module --with-http_geoip_module --with-http_gunzip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

拿到這個選項,然後放在新版本nginx裡面。執行configure

[root@master2 nginx-1.18.0]# pwd
/usr/local/nginx-1.18.0
[root@master2 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_image_filter_module --with-http_geoip_module --with-http_gunzip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
checking for GeoIP IPv6 support ... found
creating objs/Makefile

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

注意:有些人可能有疑惑,新下載的nginx在執行./configure的時候–prefix指定的目錄是需要指向舊的nginx所指向的prefix目錄還是隨便指向一個就行,答案是需要指向舊版本的nginx的安裝目錄

執行make命令

[root@master2 nginx-1.18.0]# make

執行完成之後不要執行make install指令,這點需要注意。

3、平滑升級

3.1、先備份舊的nginx二進位制可執行程式

[root@master2 nginx-1.18.0]# cd /usr/local/nginx/sbin
[root@master2 sbin]# ls
nginx
[root@master2 sbin]# cp nginx{,.bak}
[root@master2 sbin]# ls
nginx  nginx.bak

3.2、檢視未升級前的nginx版本

[root@master2 sbin]# ./nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC
xxxx
xxx

3.3、找到nginx-1.18.0新版本的nginx的二進位制執行程式

[root@master2 sbin]# cd /usr/local/nginx-1.18.0/
[root@master2 nginx-1.18.0]# ls
auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  Makefile  man  objs  README  src
[root@master2 nginx-1.18.0]# cd objs
[root@master2 objs]# ls
autoconf.err  Makefile  nginx  nginx.8  ngx_auto_config.h  ngx_auto_headers.h  ngx_modules.c  ngx_modules.o  src

上面的這個nginx就是我們要拿到的新版本的nginx可執行程式檔案。

3.4、使用nginx-1.18.0的二進位制檔案將nginx-1.16.1的二進位制檔案進行強制覆蓋

[root@master2 objs]# cp -f nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y

3.5、設定舊的服務不再接收使用者請求(下線),新服務啟動子程式接收使用者請求(上線)

先檢視當前未升級的nginx程式(這是舊版本的nginx程式)

[root@master2 objs]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1496 ?        Ss   11:42   0:00 nginx: master process sbin/nginx
nobody   17441  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17442  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17443  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17444  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17445  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process

找到nginx父程式的pid號,現在對其傳送USR2訊號

[root@master2 objs]# kill -USR2 17440                       #設定新的子程式開始接收使用者的訪問請求,舊的不再接受使用者的訪問請求

再次檢視程式

[root@master2 objs]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1496 ?        Ss   11:42   0:00 nginx: master process sbin/nginx
nobody   17441  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17442  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17443  0.0  0.0  80120  2212 ?        S    11:42   0:00 nginx: worker process
nobody   17444  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
nobody   17445  0.0  0.1  80120  2456 ?        S    11:42   0:00 nginx: worker process
root     21081  0.5  0.1  79740  4080 ?        S    20:00   0:00 nginx: master process sbin/nginx
nobody   21082  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21083  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21084  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21085  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21086  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process

現在是nginx的新老版本的程式共存的一種情況。雖然現在舊版本的nginx程式還存在,但是已經不再接受使用者的請求了。除此之外,舊版本的nginx程式也依然處於監聽的狀態,我們通過lsof命令可以看到,比如:

[root@master2 objs]# lsof -p 17440 | grep LISTEN                      # 這裡的pid號是舊版本的nginx的master程式的pid號
nginx   17440 root    6u  IPv4             120768      0t0      TCP *:http (LISTEN)

雖然在監聽,但實際不會處理新連線,因為fd已經從epoll中移出了。另外,舊master是新master的父程式,所以新master才能共享開啟的監聽埠。保留舊版本的master是為了方便回滾(當然你可以發訊號QUIT或者直接殺掉程式)

3.6、進行舊服務程式的關閉

[root@master2 objs]# kill -WINCH 17440                       # 進行舊服務程式的關閉,該pid號是舊版本的nginx的master程式的pid號

再次檢視當前nginx程式

[root@master2 objs]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1652 ?        Ss   11:42   0:00 nginx: master process sbin/nginx
root     21081  0.0  0.1  79740  4080 ?        S    20:00   0:00 nginx: master process sbin/nginx
nobody   21082  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21083  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21084  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21085  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process
nobody   21086  0.0  0.0  80192  2200 ?        S    20:00   0:00 nginx: worker process

可以看到現在的舊版本的nginx的worker程式已經全部被殺死了,只剩下的舊版本nginx的master程式

確定升級沒有任何問題的話,那麼現在我們可以把這個master程式給殺死掉。可以用kill -QUIT把舊master程式殺掉。方法已經教給大家了,但是這裡我先不殺死,因為我還要往下演示如何回退。

3.7、檢視當前nginx的版本

[root@master2 nginx]# sbin/nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_image_filter_module --with-http_geoip_module --with-http_gunzip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

可以看到現在已經升級成功了。

還可以訪問一下

[root@master2 nginx]# curl http://192.168.50.129
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
xxx
xxx
xxx

4、現在我們演示一下如何回退

這種情況主要是用於當新版本的nginx升級失敗之後,我們立馬回退到舊版本的nginx

4.1、將舊版本的nginx二進位制檔案強行覆蓋

[root@master2 sbin]# mv nginx.bak  nginx
mv: overwrite ‘nginx’? y

檢視程式

[root@master2 sbin]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1652 ?        Ss   Aug20   0:00 nginx: master process sbin/nginx
root     21081  0.0  0.1  79740  4080 ?        S    Aug20   0:00 nginx: master process sbin/nginx
nobody   21082  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   21083  0.0  0.1  80192  2452 ?        S    Aug20   0:00 nginx: worker process
nobody   21084  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   21085  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   41895  0.0  0.0  80192  2200 ?        S    10:53   0:00 nginx: worker process

4.2、向舊版本nginx程式傳送HUP訊號

[root@master2 sbin]# kill -HUP 17440                              #注意這是舊版本的nginx程式pid號

說明一下:這個命令就相當與reload指令的作用,把舊的nginx的worker程式拉起來,但是我們們並不是直接使用reload的方式來執行,而是傳送HUP訊號,它會在沒有worker程式時啟動worker程式,這點需要注意一下。
此時再次檢視程式

[root@master2 sbin]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1652 ?        Ss   Aug20   0:00 nginx: master process sbin/nginx
root     21081  0.0  0.1  79740  4080 ?        S    Aug20   0:00 nginx: master process sbin/nginx
nobody   21082  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   21083  0.0  0.1  80192  2452 ?        S    Aug20   0:00 nginx: worker process
nobody   21084  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   21085  0.0  0.0  80192  2200 ?        S    Aug20   0:00 nginx: worker process
nobody   41895  0.0  0.0  80192  2200 ?        S    10:53   0:00 nginx: worker process
nobody   42070  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42071  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42072  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42073  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42074  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process

發現多了很多worker程式,多出來的部分是舊版本的nginx程式。

4.3、讓新版本的服務停止接收使用者請求

[root@master2 sbin]# kill -USR2 21081

此時,接收使用者請求的是舊版本的nginx程式。新版本的nginx程式不再接受使用者請求

4.4、進行新版本服務程式的關閉

[root@master2 sbin]# kill -WINCH 21081

檢視一下程式

[root@master2 sbin]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1652 ?        Ss   Aug20   0:00 nginx: master process sbin/nginx
root     21081  0.0  0.1  79740  4080 ?        S    Aug20   0:00 nginx: master process sbin/nginx
nobody   42070  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42071  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42072  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42073  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42074  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process

現在,舊版本已經回退成功了,我們可以把新版本的nginx的master程式傳送QUIT程式將其退出。

4.5、kill掉新版本nginx程式

[root@master2 sbin]# kill -QUIT 21081
[root@master2 sbin]# ps aux | grep nginx
root     17440  0.0  0.0  79732  1652 ?        Ss   Aug20   0:00 nginx: master process sbin/nginx
nobody   42070  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42071  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42072  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42073  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process
nobody   42074  0.0  0.0  80120  2208 ?        S    15:42   0:00 nginx: worker process

現在已經回退成功了

相關文章