nginx熱部署詳解
原文:https://blog.csdn.net/meltsnow/article/details/90085035
前言
原理:
- nginx 支持熱加載 熱部署 ,在不打斷用戶請求的情況下更新版本
- Nginx 只所以出名,和它內部的精密設計有關。Nginx 採用了高度模塊化的設計思路,並且內部的進程主要有兩類,master 進程 和 worker 進程。其中 master 進程只有一個,worker 進程可以有多個。
- worker 進程纔是真正 working 的進程,纔是真正處理請求的進程。worker 進程全部都是 master 進程的子進程。worker 進程是以普通用戶的身份進行運行的,這樣就可以極大增加程序的安全性。就算是萬一有一個進程被劫持,那也不會有管理員權限。
- nginx 的熱部署和其併發模型有着密不可分的關係。說白了,就是因爲 master 進程的關係。當通知 ngnix 重讀配置文件的時候,master 進程會進行語法錯誤的判斷。如果存在語法錯誤的話,返回錯誤,不進行裝載;如果配置文件沒有語法錯誤,那麼 ngnix 也不會將新的配置調整到所有 worker 中。而是,先不改變已經建立連接的 worker,等待 worker 將所有請求結束之後,將原先在舊的配置下啓動的 worker 殺死,然後使用新的配置創建新的 worker。
實驗環境:
- rhel7.3版本的虛擬機
- 兩個不同版本的nginx安裝包
一、配置過程
1.下載兩個不同版本的安裝包
[root@server1 ~]# ls
nginx-1.15.9.tar.gz nginx-1.16.0.tar.gz
配置一個1.16.0版本的nginx
2.解壓1.16.0版本,作爲舊的版本
[root@server1 ~]# tar zxf nginx-1.16.0.tar.gz
[root@server1 ~]# ls
nginx-1.15.9.tar.gz nginx-1.16.0 nginx-1.16.0.tar.gz
3.關閉debug日誌,編譯,安裝
解壓出來的源碼安裝包下的文件的解釋
.
(1)關閉debug日誌
[root@server1 nginx-1.16.0]# vim auto/cc/gcc ##關閉日誌
(2)安裝依賴性
[root@server1 nginx-1.16.0]# yum install -y pcre-devel zlib-devel gcc
(3)編譯
[root@server1 nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --with-file-aio
(4)編譯之後出現了objs目錄
(5)安裝
[root@server1 nginx-1.16.0]# make
make後objs/下出現了二進制執行文件
[root@server1 nginx-1.16.0]# ls
[root@server1 nginx-1.16.0]# cd objs/
[root@server1 objs]# ls
(6)make install
[root@server1 nginx-1.16.0]# make install
make install 實際上就是將二進制執行文件和一些配置文件複製到/usr/local/nginx目錄下
4.配置nginx服務
(1)查看配置文件,第一行是nobody
不寫的話nginx進程默認用戶是nobody 可以開啓服務用ps aux查看
(2)進行語法檢測
[root@server1 conf]# ../sbin/nginx -t
(3)查看版本號
[root@server1 conf]# ../sbin/nginx -V
(4)打開服務
[root@server1 conf]# ../sbin/nginx
(5)查看進程所有人是nobody
[root@server1 conf]# ps aux | grep nginx
(6)創建nginx用戶
[root@server1 conf]# useradd nginx
[root@server1 conf]# id nginx
uid=1000(nginx) gid=1000(nginx) groups=1000(nginx)
(7)關閉之前的nginx服務
[root@server1 conf]# ../sbin/nginx -s stop
(8)編輯配置文件
[root@server1 conf]# vim nginx.conf ##改變用戶
user nginx nginx;
worker_processes 2;
(9)先在系統安全的配置文件中設定nginx用戶允許的最大文件數
[root@server1 conf]# vim /etc/security/limits.conf
(10)再次編輯nginx配置文件,在配置文件設置最大併發數
[root@server1 conf]# vim nginx.conf ##改變最大併發數
12 events {
13 worker_connections 65535;
14 }
(11)打開服務,查看進程,進程所有人是nginx用戶
[root@server1 conf]# ../sbin/nginx
[root@server1 conf]#
[root@server1 conf]# ps aux
(12)打開瀏覽器測試,訪問成功
訪問到nginx的默認頁面
二、更新nginx
1.解壓另一個版本的nginx
[root@server1 ~]# cd nginx-1.15.9
[root@server1 nginx-1.15.9]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
2.編譯安裝,同樣關閉debug日誌,不取消版本號方便觀察
注意:千萬不要make insatll 否則會把二進制執行文件複製到/usr/local下的nginx目錄 覆蓋之前的文件
(1)編譯
[root@server1 nginx-1.15.9]# ./configure --prefix=/usr/local/nginx --with-file-aio
(2)同樣出現objs目錄
(3)安裝
[root@server1 nginx-1.15.9]# make
objs目錄下的文件增加
[root@server1 nginx-1.15.9]# cd objs/
[root@server1 objs]# ls
(4)備份舊版本的nginx二進制執行文件
[root@server1 objs]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ls
nginx
[root@server1 sbin]# cp nginx nginx.old
[root@server1 sbin]# ls
nginx nginx.old
(5)替換二進制文件(將新版本的二進制執行文件覆蓋過去,要加 -f 否則報錯正忙)
[root@server1 objs]# cp -f nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y
(6)查看nginx進程,一個master,兩個worker
[root@server1 objs]# ps -ef | grep nginx
(7)查看當前版本
[root@server1 objs]# cd -
/usr/local/nginx/sbin
[root@server1 sbin]# ./nginx -V
注意:雖然當前版本已經變成了1.15.9版本,這個時候表面上看起來是更新成了新版本,但還是舊版本的在工作,接收客戶端請求的仍然是1.16.0版本的nginx,這就有了下面的平滑升級
三、平滑升級
1.kill -USR2 舊版本的主進程號 (讓舊版本的worker進程不再接受請求)
[root@server1 objs]# kill -USR2 4810
[root@server1 objs]# ps -ef | grep nginx
可以看到現在有2個master,4個worker
2.kill -WINCH 舊版本的主進程號 (關閉舊版本的worker進程)
[root@server1 objs]# kill -WINCH 4810
[root@server1 objs]# ps -ef | grep nginx
可以看到現在有2個master,2個worker
舊版本的worker被關閉
3.查看版本號現在用的是新版本
四、版本的回退(如果升級後有問題可以立即回退來恢復)
命令 | 作用 |
---|---|
kill -USER2 進程號 | 不再讓worker進程接受請求,當前請求處理完就讓worker進程退出 |
kill -WINCH 進程號 | 處理完關閉 |
kill -HUP 進程號 | 啓動進程 |
1.先將二進制執行文件還原,不加-f會提示文件正忙
操作前的進程nginx情況
開始回退
[root@server1 objs]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ls
nginx nginx.old
[root@server1 sbin]# cp nginx.old nginx
cp: overwrite ‘nginx’? y
cp: cannot create regular file ‘nginx’: Text file busy
[root@server1 sbin]#
[root@server1 sbin]# cp -f nginx.old nginx
cp: overwrite ‘nginx’? y
2.現在依舊是2個master 2個worker
3.kill -HUP 舊版本的進程號 (拉起舊版本的worker進程)
[root@server1 sbin]# kill -HUP 4810
[root@server1 sbin]# ps -ef | grep nginx
2個master 4個worker
5.kill -WINCH 新版本的主進程號 (關閉新版本的worker進程)
[root@server1 sbin]# kill -WINCH 16940
[root@server1 sbin]# ps -ef | grep nginx
6.查看版本號,是舊版本的nginx
[root@server1 sbin]# /usr/local/nginx/sbin/nginx -V
</div>