基於 LNMP 的 Nginx 百萬併發之路 (四)熱部署

cn-five發表於2020-09-12

Nginx 熱部署或者說平滑升級是指不中斷伺服器服務同時更新版本。通俗地說就是不打斷使用者請求,讓使用者的體驗感處於一個高水平線。可以試想,如果一個使用者在購物車放置了大量限時優惠商品,正準備結算,突然網頁出現工程師 24 小時修復中的提示頁面,會很煩惱吧。

訊號量

Nginx 的熱部署跟 Linux 訊號量機制有密切關係,先檢視 Linux 訊號量 kill -l,顯示如下

 1) SIGHUP     2) SIGINT             3) SIGQUIT      4) SIGILL        5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE             9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX

一共 64 種,其中常見的命令為 kill -15 表示快速關閉,kill -9 強制關閉,kill -1 重新讀取配置檔案,kill - 17 父子程式通訊等等。

訊號量 描述
USR2 Upgrade Executable on the fly 平滑升級
WINCH Gracefully shutdown the worker processes 優雅關閉舊的程式(配合USR2來進行升級)
HUP Configuration reload ,Start the new worker processes with a new configuration Gracefully shutdown the old worker processes 改變配置檔案,平滑重讀配置檔案

熱部署

用全路徑形式開啟 Nginx

/opt/nginx/sbin/nginx

以防萬一,備份 Nginx 二進位制檔案與主配置檔案,其實安裝新版本後也會在 sbin 目錄生成一個 nginx.old 二進位制檔案,這屬於舊版本的。

cp /opt/nginx/sbin/nginx /opt/nginx/sbin/nginx.bk
cp /opt/nginx/conf/nginx.conf /opt/nginx/conf/nginx.conf.bk

ls /opt/nginx/sbin

nginx
nginx.bk

下載需要更新的 Nginx 版本

wget http://nginx.org/download/nginx-1.19.2.tar.gz

注意安裝目錄須於原版本一致,檢視安裝目錄 nginx -V

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=/opt/nginx --conf-path=/opt/nginx/conf/nginx.conf --user=nginx --group=nginx --pid-path=/opt/nginx/pid/nginx.pid --error-log-path=/opt/nginx/logs/error.log --with-pcre=/opt/source/pcre-8.44 --with-zlib=/opt/source/zlib-1.2.11 --with-http_ssl_module --with-http_image_filter_module --with-http_stub_status_module --http-log-path=/opt/nginx/logs/access.log --with-http_auth_request_module

lscpu

CPU(s): 4

ps -ef | grep nginx | grep -v grep

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2089   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2090   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2091   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2092   2088  0 01:03 ?        00:00:00 nginx: worker process

傳送 USE2 命令

kill -s SIGUSR2 2088

再次檢視 Nginx 程式,發現同時存在 8 個子程式,其中多出的 4 個是使用新版本的子程式。

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2089   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2090   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2091   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2092   2088  0 01:03 ?        00:00:00 nginx: worker process
root       2096   2088  0 01:04 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2097   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2098   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2099   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2100   2096  0 01:04 ?        00:00:00 nginx: worker process

ll /opt/nginx/logs/

nginx.pid # 新版本程式 id 2096
nginx.pid.oldbin # 舊版本程式 id 2088

傳送 WINCH 訊號,關閉舊的子程式。

kill -s SIGWINCH 2088

檢視現有版本 nginx -V

nginx version: nginx/1.19.2

優雅關閉舊 master 程式。在這一步可以不關閉舊 master 程式,測試新版本,如果不達預期可以直接回滾至舊版本。

kill -s SIGQUIT 2088

這時候用 ps 命令檢視,已經為新版本的 Nginx 程式(演示)。

root       2096      1  0 01:04 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2097   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2098   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2099   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2100   2096  0 01:04 ?        00:00:00 nginx: worker process

回滾

如果測試後發現新版本不適應現有業務,可以進行像資料庫那樣的回滾操作。

kill -s SIGHUP 2088 # 此命令將拉起舊的子程式
kill -s SIGQUIT 2096  # r讓新版本的子程式優雅退出

ps -ef | grep nginx | grep -v grep 檢視,發現舊的 master 已經啟動 4 個子程式,新版本的主程式與子程式完全退出。

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2100   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2101   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2102   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2103   2088  0 01:03 ?        00:00:00 nginx: worker process
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章