Nginx 平滑升級(jí)的實(shí)戰(zhàn)指南!(含備份+業(yè)務(wù)0中斷+回滾)
今天分享一下Nginx如何平滑升級(jí),做到零中斷。
在實(shí)際生產(chǎn)環(huán)境,安全部門一般都會(huì)定期去掃描程序漏洞,基本都需要升級(jí)版本。
部分運(yùn)維人員的做法是:停服務(wù)--> 刪除舊版本nginx-->安裝新版本nginx-->啟動(dòng)服務(wù)。
這種方式需要停服務(wù),非常影響用戶體驗(yàn)感,所以我下面介紹一下如何進(jìn)行不停機(jī)且安全可控得進(jìn)行平滑升級(jí)Nginx。
1. 實(shí)驗(yàn)環(huán)境說明
- 操作系統(tǒng):Rockylinux9.4
- 當(dāng)前nginx是編譯安裝
- 部署路徑:/data/nginx
- 從nginx1.26.2升級(jí)到1.29.0
2. 升級(jí)前先備份!非常關(guān)鍵!
線上升級(jí),沒備份 = 自殺式升級(jí)。
全量備份:
tar -zcvf /data/nginx-backup-$(date +%F).tar.gz /data/nginx/
回滾時(shí)你只需 tar -zxvf + reload,1 分鐘恢復(fù)原狀。
3. 確認(rèn)原版本和編譯參數(shù)
[root@webserver data]# nginx -V
nginx version: nginx/1.26.2
built by gcc 11.5.0 20240719 (Red Hat 11.5.0-5) (GCC)
built with OpenSSL 3.2.2 4 Jun 2024
TLS SNI support enabled
configure arguments: --prefix=/data/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre --with-stream --with-stream_ssl_module
非常重要!新版本必須用相同參數(shù)編譯才能平滑替換,不過可以新增參數(shù)!
4. 安裝依賴
dnf install -y gcc make zlib-devel pcre-devel openssl-devel wget
這一步可以省略,一般編譯舊版本時(shí)已經(jīng)安裝了依賴。
5. 下載并編譯 Nginx 新版本
(1) 下載源碼
版本可以具體根據(jù)漏掃要求,一般是建議最新版本,我這邊選1.29.0版本:
wget https://nginx.org/download/nginx-1.29.0.tar.gz
tar -zxvf nginx-1.29.0.tar.gz
cd nginx-1.29.0
(2) 使用原配置參數(shù)重新編譯
這里也可以添加一些新的參數(shù),但是盡量不要?jiǎng)h除以前的參數(shù),建議在已有基礎(chǔ)添加新參數(shù)。
./configure --prefix=/data/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module
make
注意注意:千萬不要 make install,避免直接覆蓋現(xiàn)有 Nginx!
6. 平滑升級(jí)核心流程
(1) 替換 Nginx 可執(zhí)行文件
# 移動(dòng)舊版本可執(zhí)行文件
mv /data/nginx/sbin/nginx /data/nginx/nginx/sbin/nginx.old
# 將新版本的執(zhí)行文件放置在安裝目錄下
cp ./objs/nginx /data/nginx/sbin/nginx
# 檢測(cè)Nginx進(jìn)程,可見舊的版本進(jìn)程還在運(yùn)行
ps -ef |grep nginx
(2)啟動(dòng)新主進(jìn)程(平滑切換)
# 殺掉舊版nginx主進(jìn)程,讓新進(jìn)程重新生成
kill -USR2 `cat /data/nginx/logs/nginx.pid`
# 上面引用部分主要是找出nginx的PID,你也可以根據(jù)ps來找。
此時(shí)存在4個(gè)進(jìn)程. 2個(gè)舊版nginx進(jìn)程 2個(gè)新版nginx進(jìn)程。
新的 master 進(jìn)程加載新版本。
老版本PID文件變?yōu)?nbsp;.pid.oldbin,仍然工作中:
(3) 優(yōu)雅關(guān)閉舊 worker進(jìn)程
kill -WINCH `cat /data/nginx/logs/nginx.pid.oldbin`
舊worker 會(huì)逐步停止服務(wù),連接自動(dòng)轉(zhuǎn)移到新版本,舊master進(jìn)程還在。
7. 驗(yàn)證是否升級(jí)成功
查看版本:
nginx -v
檢查日志無報(bào)錯(cuò):
tail /data/nginx/logs/error.log
確認(rèn)監(jiān)聽端口仍在線:
netstat -lntup |grep nginx
多核 CPU 下也可觀察進(jìn)程切換:
ps -ef | grep nginx
8. 結(jié)束舊主進(jìn)程
等業(yè)務(wù)確認(rèn)OK后,沒問題,就可以殺掉舊的master進(jìn)程了。
kill -QUIT `cat /data/nginx/logs/nginx.pid.oldbin`
# 再次檢查
ps -ef |grep nginx
此時(shí)舊版進(jìn)程徹底退出,升級(jí)完成!
9. 快速回滾操作
如果升級(jí)后出問題,只需執(zhí)行:
cp /data/nginx/sbin/nginx.bak /data/nginx/sbin/nginx
nginx -s reload
也可以恢復(fù)整個(gè) Nginx 安裝目錄:根據(jù)之前那個(gè)備份目錄直接解壓后重載nginx:
tar -zxvf /data/nginx-backup-YYYY-MM-DD.tar.gz -C /
nginx -s reload
謹(jǐn)記:先備份后操作!如果可以測(cè)試環(huán)境先行!