網站首頁 編程語言 正文
前言
環境:centos7.9、源碼編譯安裝的nginx
nginx支持的kill信號
我們源碼編譯安裝的nginx,其啟動通過直接執行 /usr/local/nginx/sbin/nginx
來啟動nginx,停止,退出,重開日志,重載配置是通過/usr/local/nginx/sbin/nginx -s stop|quit|reopen|reload
來發送信息給master進程實現的。除了這種方式,官方說明文檔顯示還提供kill命令來發送對應的信息給nginx主進程,nginx的master進程接收到這些信號就會執行對應的操作,如下:
kill 命令傳送信號給nginx的master進程,注意是發送給master進程:
TERM、INIT :強制退出,當前的請求不執行完成就退出 等介于 ./nginx -s stop
QUIT :優雅退出,等待請求執行完成后退出 等介于 ./nginx -s quit
HUP :重載配置文件,用新的配置文件啟動新的work進程并優雅的關閉舊的work進程,等介于./nginx -s reload
USR1 :重開日志,等價于./nginx -s reopen
USR2 :平滑的升級nginx,拉起一個新的nginx主進程,同時做到不停止舊的nginx主進程
WINCH :優雅的關閉worker進程,發送一個WINCH信號給master進程,告知其優雅的關閉worker進程(一般不常用)
演示示例:
kill -TERM 195916 #強制停止nginx,等價于 ./nginx -s stop
kill -INT 197019 #強制停止nginx,等價于 ./nginx -s stop
kill -QUIT 197073 #優雅的退出nginx,等價于 ./nginx -s quit
kill -HUP 197075 #重載配置文件,等價于 ./nginx -s reload
kill -USR1 197220 #重開日志,等價于 ./nginx -s reopen
kill -WINCH 197222 #優雅的關閉worker進程
備注:信號都是發送給nginx的master進程的
先安裝一個nginx-1.18.0舊版本來演示
useradd -s /sbin/nologin -M nginx
yum -y install gcc gcc-c++ make pcre pcre-devel zlib-devel zlib openssl-devel openss
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_modul
make -j 8
make install
cd usr/local/nginx/sbin
./nginx
ps -ef | grep nginx
root 1679 1 0 11:23 ? 00:00:00 nginx: master process ./nginx
nginx 1680 1679 0 11:23 ? 00:00:00 nginx: worker process
nginx 1681 1679 0 11:23 ? 00:00:00 nginx: worker process
#下面開始平滑升級nginx為nginx-1.22.0版本,不停nginx升級,實現平滑升級nginx
方法一、 nginx平滑升級
1、如果我們想要更換nginx版本,升級為更高版本的nginx,無非就是重新編譯安裝新版本的nginx,然后停止舊版本nginx,啟動新版本nginx。這切換期間勢必存在nginx服務不可用。(因為我們不能同時啟動兩個版本的nginx,會存在端口沖突的問題)
2、官網給我們提供了上面問題的解決方案,即平滑升級nginx,所謂平滑升級是指舊的nginx不停止,新的nginx又可以啟動,即同時存在舊的nginx和新的nginx,當舊的nginx請求處理完畢,關閉舊的nginx。這就要用到我們前面所說的 USR2 信號來實現nginx的平滑升級了。
USR2 平滑啟動nginx進程
WINCH 優雅的停止worker進程
QUIT 優雅的停止舊的master進程
先查看現在的nginx的版本:
/usr/local/nginx/sbin/nginx -V
ginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
編譯安裝高版本的nginx,編譯參數要與原來舊版本參數的一致(只多不少),安裝路徑要與原來舊版本安裝路徑一樣;
注意:升級新版本,新版本的安裝路徑要與舊版本的安裝路徑保持一致,安裝完成,會在sbin目錄下存在一個nginx(新版本)、nginx.old(舊版本);
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
make -j 8 && make install
[root@nginx ~]# cd /usr/local/nginx/sbin #進入nginx的目錄
[root@nginx sbin]# ll #查看nginx的可執行文件,可以看到我們現在有兩個nginx的可執行文件
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 12:47 nginx #新版本的nginx-1.22.0
-rwxr-xr-x 1 root root 5952184 Sep 23 11:22 nginx.old #原來舊版本nginx-1.18.0被備份為nginx.old了
[root@nginx sbin]# ./nginx -V #查看nginx的版本,確認是新版本的nginx-1.22.0
nginx version: nginx/1.22.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
[root@nginx sbin]# ./nginx.old -V #查看nginx的版本,確認是舊版本的nginx-1.18.0
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
[root@nginx sbin]#
這時候直接./nginx 啟動新版本肯定是報錯的,因為端口被占用,我們需要使用 USR2 來平滑升級nginx
#先查看舊版本的nginx的進程
[root@nginx sbin]# ps -ef | grep nginx
root 1679 1 0 11:23 ? 00:00:00 nginx: master process ./nginx #得到舊版本的nginx的master進程pid
nginx 1851 1679 0 11:25 ? 00:00:00 nginx: worker process
nginx 1852 1679 0 11:25 ? 00:00:00 nginx: worker process
[root@nginx sbin]#
#使用 kill -USR2 舊的主進程號 命令來平滑升級
[root@nginx sbin]# kill -USR2 1679 #向舊版本nginx的master進程發送USR2信號
#再查看nginx的進程,這時就啟動新版本的nginx進程,此時同時存在新舊版本的nginx進程
[root@nginx sbin]# ps -ef | grep nginx
root 1679 1 0 11:23 ? 00:00:00 nginx: master process ./nginx #這是舊版本的nginx/1.18.0
nginx 1851 1679 0 11:25 ? 00:00:00 nginx: worker process #這是舊版本的nginx/1.18.0
nginx 1852 1679 0 11:25 ? 00:00:00 nginx: worker process #這是舊版本的nginx/1.18.0
root 9336 1679 0 12:55 ? 00:00:00 nginx: master process ./nginx #這是新版本的nginx/1.22.0
nginx 9337 9336 0 12:55 ? 00:00:00 nginx: worker process #這是新版本的nginx/1.22.0
nginx 9338 9336 0 12:55 ? 00:00:00 nginx: worker process #這是新版本的nginx/1.22.0
#先使用 kill -WINCH 舊的主進程號 命令優雅的關閉舊版本的worker進程
[root@nginx sbin]# kill -WINCH 1679 #向舊版本nginx的master進程發送WINCH信號,告知其優雅的停止worker進程
#確認nginx升級沒有問題了,再使用命令 kill -QUIT 舊的主進程號 優雅的關閉舊版本的nginx master進程
[root@nginx sbin]# kill -QUIT 1679 #向舊版本nginx的master進程發送QUIT信號,告知其優雅的退出
#至此,此時已經完成了nginx版本的平滑升級
方法二、 nginx平滑升級
編譯安裝高版本的nginx:
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
#預編譯完成后會得到一個Makefile 文件,我們來看下這個文件的內容,如下:
[root@nginx nginx-1.22.0]# cat Makefile
default: build
clean:
rm -rf Makefile objs
.PHONY: default clean
build:
$(MAKE) -f objs/Makefile
install:
$(MAKE) -f objs/Makefile install
modules:
$(MAKE) -f objs/Makefile modules
upgrade:
/usr/local/nginx/sbin/nginx -t
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` #平滑升級
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin` #優雅的關閉舊版本的nginx
.PHONY: build install modules upgrade
[root@nginx nginx-1.22.0]#
#如上看到的,make 命令有個參數upgrade,這個參數就是平滑升級的,看起內容我看應該可以看到,其平滑升級的原理仍然是我們前面方法一的說的,先發送 USR2 信號給舊的nginx master進程告知其平滑升級,拉起新版本的nginx進程,然后再發送QUIT信號給舊版本的master進程,優雅的關閉舊版本的nginx。
make install && make upgrade #直接平滑升級,
[root@nginx sbin]# ll
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 17:36 nginx #新版本的nginx
-rwxr-xr-x 1 root root 5952184 Sep 23 17:27 nginx.old #就版本的nginx
[root@nginx sbin]#
[root@nginx sbin]# ps -ef | grep nginx #現在只有新版本的nginx
root 31946 1 0 17:36 ? 00:00:00 nginx: master process ./nginx
nginx 31947 31946 0 17:36 ? 00:00:00 nginx: worker process
root 32137 15942 0 17:40 pts/4 00:00:00 grep --color=auto nginx
[root@nginx sbin]#
#再次,平滑升級完成
方法三、 nginx平滑升級(保守方法)
同理,解壓編譯新版本的nginx,但此時的安裝路徑安裝在一個全新的目錄,不再與原來舊版本的安裝路徑一樣。
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
./configure --prefix=/usr/local/nginx2 --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
make -j 8 && make install #安裝全新版本的nginx
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old #備份原來的舊版本的nginx,備份不影響正在運行的nginx進程
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/ #將新版本的nginx可執行文件復制到舊版本的安裝路徑下
#同理,下面的步驟仍然是發送信號SER2給舊版本的nginx的master進程進行平滑升級nginx,然后再關閉舊版本的worker進程和master進程
[root@nginx sbin]# kill -USR2 1679 #向舊版本nginx的master進程發送USR2信號
#先使用 kill -WINCH 舊的主進程號 命令優雅的關閉舊版本的worker進程
[root@nginx sbin]# kill -WINCH 1679 #向舊版本nginx的master進程發送WINCH信號,告知其優雅的停止worker進程
#確認nginx升級沒有問題了,再使用命令 kill -QUIT 舊的主進程號 優雅的關閉舊版本的nginx master進程
[root@nginx sbin]# kill -QUIT 1679 #向舊版本nginx的master進程發送QUIT信號,告知其優雅的退出
#至此,此時已經完成了nginx版本的平滑升級
nginx版本回退
如果在使用新版本的nginx過程中發現新版本存在問題,那么可以進行nginx版本回退,回退到舊版本的nginx,。
版本回退可以分2中情況,如下:
1、事前對舊版本nginx進行備份,若出現問題,直接將舊版本重新拷貝會/usr/local目錄下,重啟nginx舊版本操作,執行如下:
#停止nginx服務進行版本回退
killall nginx
cp /usr/local/nginx-1.18.0.bak /usr/local/nginx
/usr/local/nginx/sbin/nginx
#檢查nginx狀態
ps -ef |grep nginx
2、在新版本nginx的master進程和舊版本的master進程同時存在時,即只關閉了舊版本的worker進程沒有關閉舊版本的master進程的情況下,可以這樣回滾,如下:
#向舊版本的master進程發送HUP信號,重載配置,會重新拉起新的worker進程
kill -HUP 舊masterPID # HUP是重載配置,會重新啟動worker進程
#關閉新版本nginx的master進程,并將原sbin目錄下的nginx.old(舊版本nginx二進制文件)重新改回nginx,以便管理nginx
kill -WINCH 新master的PID #優雅額關閉新版本的worker進程
kill -QUIT 新master的PID #優雅額關閉新版本的matser進程
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak #先備份新版本的nginx可執行文件
mv nginx.old nginx #將舊版本的nginx可執行文件恢復回來
總結
nginx支持的kill發送以下的信號:
kill -TERM 195916 #強制停止nginx,等價于 ./nginx -s stop
kill -INT 197019 #強制停止nginx,等價于 ./nginx -s stop
kill -QUIT 197073 #優雅的退出nginx,等價于 ./nginx -s quit
kill -HUP 197075 #重載配置文件,等價于 ./nginx -s reload
kill -USR1 197220 #重開日志,等價于 ./nginx -s reopen
kill -USR2 197220 #平滑升級nginx
kill -WINCH 197222 #優雅的關閉worker進程
備注:信號都是發送給nginx的master進程的
平滑升級nginx的大概思路:
方法一、
1、編譯安裝高版本的nginx,其./configure預編譯的參數要與原來舊版本的參數一致,包括安裝路徑也要一致;
2、make -j 10 && make install 編譯安裝;
3、安裝完成之后,在/usr/local/nginx/sbin/目錄下就會存在一個可執行文件,nginx、nginx.old,前者是新版本的可執行文件,后者是舊版本的可執行文件;
4、使用 kill -USR2 舊版本的masterPID 命令進行平滑升級,此時就會同時存在新版本舊版本的nginx進程;
5、使用 kill -WINCH 舊版本的masterPID 命令優雅的關閉舊版本的worker進程
6、確認新版本的nginx進程沒有問題后,此時可以使用 kill -QUIT 舊版本的masterPID 命令優雅的關閉舊版本的master進程;
7、nginx升級已完成。
方法二、
1、編譯安裝高版本的nginx,其./configure預編譯的參數要與原來舊版本的參數一致,包括安裝路徑也要一致;
2、make install && make upgrade 編譯安裝,make upgrade直接平滑升級;
3、安裝完成之后,在/usr/local/nginx/sbin/目錄下就會存在一個可執行文件,nginx、nginx.old,前者是新版本的可執行文件,后者是舊版本的可執行文件;
4、此時平滑升級完成了,ps -ef | grep nginx 查看只會有新版本的nginx,因為當你執行make upgrade的時候,其實已經發送了kill -QUIT 信號給舊版本的nginx,所以舊版本的nginx進程已經優雅的退出了。
5、nginx升級已完成。
方法三、(保守方法)
1、解壓編譯新版本的nginx,但此時的安裝路徑安裝在一個全新的目錄,不再與原來舊版本的安裝路徑一樣;
2、備份舊版本的可行性文件,復制新版本的nginx的可執行文件
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old #備份原來的舊版本的nginx,備份不影響正在運行的nginx進程
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/ #將新版本的nginx可執行文件復制到舊版本的安裝路徑下
3、使用 kill -USR2 舊版本的masterPID 命令進行平滑升級,此時就會同時存在新版本舊版本的nginx進程;
4、使用 kill -WINCH 舊版本的masterPID 命令優雅的關閉舊版本的worker進程
5、確認新版本的nginx進程沒有問題后,此時可以使用 kill -QUIT 舊版本的masterPID 命令優雅的關閉舊版本的master進程;
6、nginx升級已完成。
版本回退:
1、如果事前對舊版本nginx進行備份,若出現問題,直接將舊版本重新拷貝會/usr/local目錄下,重啟nginx舊版本操作,執行如下:
#停止nginx服務進行版本回退
killall nginx
cp /usr/local/nginx-1.18.0.bak /usr/local/nginx
/usr/local/nginx/sbin/nginx
#檢查nginx狀態
ps -ef |grep nginx
2、在新版本nginx的master進程和舊版本的master進程同時存在時,即只關閉了舊版本的worker進程沒有關閉舊版本的master進程的情況下,可以這樣回滾,如下:
#向舊版本的master進程發送HUP信號,重載配置,會重新拉起新的worker進程
kill -HUP 舊masterPID # HUP是重載配置,會重新啟動worker進程
#關閉新版本nginx的master進程,并將原sbin目錄下的nginx.old(舊版本nginx二進制文件)重新改回nginx,以便管理nginx
kill -WINCH 新master的PID #優雅額關閉新版本的worker進程
kill -QUIT 新master的PID #優雅額關閉新版本的matser進程
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak #先備份新版本的nginx可執行文件
mv nginx.old nginx #將舊版本的nginx可執行文件恢復回來
原文鏈接:https://blog.csdn.net/MssGuo/article/details/127002480
相關推薦
- 2022-03-23 .NET微服務架構CI/CD自動打包鏡像_實用技巧
- 2022-04-16 WPF框架Prism中區域Region用法介紹_實用技巧
- 2022-09-30 python計算列表元素與乘積詳情_python
- 2022-03-04 element-ui 固定彈窗底部的按鈕
- 2022-03-18 C語言回溯法解八皇后問題(八皇后算法)_C 語言
- 2022-06-30 MongoDB排序時內存大小限制與創建索引的注意事項詳解_MongoDB
- 2023-04-04 C語言對于volatile與gcc優化的探究_C 語言
- 2022-05-03 Shell內置命令教程之alias和echo_linux shell
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支