1. 程式人生 > 其它 >Linux - Nginx 平滑升級

Linux - Nginx 平滑升級

當公司中無前面的排程器時,需要在不中斷使用者連結的情況下,進行平滑升級,可採用如下方法

# 備份當前nginx二進位制檔案,注意自己安裝路徑,我的是自己編譯安裝自己指定路徑
[21:12:22 root@centos8 sbin]#ll /apps/nginx/sbin/
total 14964
-rwxr-xr-x 1 root root 7595800 Jul 11 21:02 nginx
-rwxr-xr-x 1 root root 7595800 Jul 11 21:14 nginx.bk


#如果是yum安裝
[21:40:02 root@centos8 ~]#ll /usr/sbin/nginx
-rwxr-xr-x 1
root root 1264168 Oct 8 2019 /usr/sbin/nginx

# 下載你需要更新的版本,請注意偶數版本號為穩定版本,奇數版為測試環境版本

# 我是從1.18.0 升級到1.20.0

[21:43:40 root@centos8 sbin]#wget http://nginx.org/download/nginx-1.20.0.tar.gz

# 解壓縮,編譯,make, 不需要make install

tar xf nginx-1.20.0.tar.gz -C /usr/local/src
cd /usr/local/src/nginx-1.20.0/

# 編譯選項與舊版本的編譯選項要一直,可以先用nginx 
-V 檢視編譯選項 ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module # 不做make install make
#上述完成以後,會在當前我解壓縮nginx的objs下面產生一個nginx二進位制檔案 [21:44:32 root@centos8 sbin]#cd /usr/local/src/nginx-1.20.0/objs/ [21:48:05 root@centos8 objs]#ll total 7708 -rw-r--r-- 1 root root 18498 Jul 11 21:21 autoconf.err -rw-r--r-- 1 root root 53134 Jul 11 21:21 Makefile -rwxr-xr-x 1 root root 7724128 Jul 11 21:21 nginx -rw-r--r-- 1 root root 5517 Jul 11 21:21 nginx.8 -rw-r--r-- 1 root root 7914 Jul 11 21:21 ngx_auto_config.h -rw-r--r-- 1 root root 657 Jul 11 21:21 ngx_auto_headers.h -rw-r--r-- 1 root root 8868 Jul 11 21:21 ngx_modules.c -rw-r--r-- 1 root root 60184 Jul 11 21:21 ngx_modules.o drwxr-xr-x 9 root root 91 Jul 11 21:21 src # 複製新版本的nginx二進位制檔案到就二進位制檔案路徑,覆蓋它,如果cp不行可用mv覆蓋 mv nginx /apps/nginx/sbin/nginx # 此時就可查詢nginx的版本 [21:50:02 root@centos8 ~]#nginx -V nginx version: nginx/1.20.0 built by gcc 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module #但是依然是舊版本nginx在做服務,用USR2訊號把新的nginx作為舊nginx 的子程序 kill -USR2 `cat /apps/nginx/logs/nginx.pid` [21:26:03 root@centos8 ~]#ps auxf | grep nginx root 14058 0.0 0.0 12132 1064 pts/0 S+ 21:28 0:00 | \_ grep --color=auto nginx root 6727 0.0 0.1 42440 2672 ? Ss 21:12 0:00 nginx: master process /apps/nginx/sbin/nginx nginx 6728 0.0 0.2 77096 5052 ? S 21:12 0:00 \_ nginx: worker process root 14055 0.0 0.3 42468 6112 ? S 21:28 0:00 \_ nginx: master process /apps/nginx/sbin/nginx nginx 14056 0.0 0.2 77212 4668 ? S 21:28 0:00 \_ nginx: worker process # 此時pid檔案會產生一個pid.oldbin,這個檔案是舊nginx的程序號,新的pid檔案時新的master nginx程序號 [21:29:47 root@centos8 ~]#ll /apps/nginx/logs/ total 16 -rw-r--r-- 1 root root 437 Jul 11 21:13 access.log -rw-r--r-- 1 root root 312 Jul 11 21:28 error.log -rw-r--r-- 1 root root 6 Jul 11 21:28 nginx.pid -rw-r--r-- 1 root root 5 Jul 11 21:12 nginx.pid.oldbin # 用訊號WINCH優雅的關閉舊master的worker程序 kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin` [21:30:24 root@centos8 ~]#ps auxf | grep nginx root 14058 0.0 0.0 12132 1064 pts/0 S+ 21:28 0:00 | \_ grep --color=auto nginx root 6727 0.0 0.1 42440 2672 ? Ss 21:12 0:00 nginx: master process /apps/nginx/sbin/nginx nginx 6728 0.0 0.2 77096 5052 ? S 21:12 0:00 \_ nginx: worker process -> 這個worker程序會被刪除 root 14055 0.0 0.3 42468 6112 ? S 21:28 0:00 \_ nginx: master process /apps/nginx/sbin/nginx nginx 14056 0.0 0.2 77212 4668 ? S 21:28 0:00 \_ nginx: worker process

# 注意接下來比較重要,因為如果想要回滾舊版本,此時就是回滾時刻 # 傳送HUB訊號給舊版本
kill -HUB 舊master程序號 kill -quit 新master程序號 ### 此時回滾成功 #當然還有其他回滾方法,此次不做介紹 # 當確認無問題以後,傳送quit關閉老版本 kill -quit 舊master程序號

# Nginx的I/O特性,阻塞,非阻塞,多路複用,訊號驅動,非同步

其中多路複用中涉及三個系統呼叫,SELECT,POLL,EPOLL,

SELECT: 連結只有1024,用陣列存放,然後採用遍歷演算法,其時間複雜度為O(n)

POLL:連結無上限,用連結串列存放,然後採用遍歷演算法,其時間複雜度為O(n)

EPOLL:最優,連結無上限,用hash表存放,採用紅黑樹演算法,完成會用事件通知的形式,其時間複雜度為O(1)