回覆列表
  • 1 # 程式設計師米兜

    01前言

    Nginx("engine x")是一款是由俄羅斯的程式設計師Igor Sysoev所開發高效能的 Web和 反向代理伺服器,也是一個 IMAP/POP3/SMTP 代理伺服器。

    在高連線併發的情況下,Nginx是Apache伺服器不錯的替代品。由於它的記憶體佔用少,啟動極快,高併發能力強,在網際網路專案中廣泛應用。

    上圖簡單展示了Nginx的部署,Nginx類似閘道器。

    02正向代理與反向代理

    正向代理與反向代理有什麼區別暱?我們就不廢話先,直接上圖

    這兩圖這麼一整,估計也很難理解清楚那個是正向代理,那個是反向代理。那我現在詳細解釋一下吧。

    正向代理形如1圖,我們在aws上申請首次註冊送12月的伺服器,然後它就是我們的VPN了,然後我們透過它就可以訪問YouTube了。不知道大夥能不能明白,正向代理是我們客戶端發起的,客戶端做出調整。

    反向代理形如2圖,伺服器A,伺服器B,服務C部署在內網,我們透過Nginx暴露一個網路地址,小夥伴們就可以訪問我們了。

    這麼講不知道能不能解釋清楚,大夥可以繼續看一下下面這個比喻:

    正向代理:客戶端 <一> 代理 一>服務端

    正向代理簡單地打個租房的比方:

    A(客戶端)想租C(服務端)的房子,但是A(客戶端)並不認識C(服務端)租不到。B(代理)認識C(服務端)能租這個房子所以你找了B(代理)幫忙租到這個房子。

    這個過程中C(服務端)不認識A(客戶端)只認識B(代理)C(服務端)並不知道A(客戶端)租了房子,只知道房子租給了B(代理)。

    反向代理:客戶端 一>代理 <一> 服務端

    反向代理也用一個租房的例子:

    A(客戶端)想租一個房子,B(代理)就把這個房子租給了他。這時候實際上C(服務端)才是房東。B(代理)是中介把這個房子租給了A(客戶端)。

    這個過程中A(客戶端)並不知道這個房子到底誰才是房東。

    03Master-Worker模式

    啟動Nginx後,其實就是在80埠啟動了Socket服務進行監聽,如圖所示,Nginx涉及Master程序和Worker程序。

    1--程序數,建議設定和CPU個數一樣或2倍

    2--日誌級別,預設error級別

    3--Nginx 啟動後的pid 存放位置

    4--配置每個程序的連線數,總的連線數= worker_processes * worker_connections根據物理記憶體大小來配置,預設1024

    Master程序的作用是?

    讀取並驗證配置檔案nginx.conf;管理worker程序;

    Worker程序的作用是?

    每一個Worker程序都維護一個執行緒(避免執行緒切換),處理連線和請求;注意Worker程序的個數由配置檔案決定,一般和CPU個數相關(有利於程序切換),配置幾個就有幾個Worker程序。

    由圖1可以看到,我這邊配了兩個worker_processes,所以有兩個worker程序。

    04如何做到高併發下的高效處理?

    上文已經提及Nginx的worker程序個數與CPU繫結、worker程序內部包含一個執行緒高效迴環處理請求,這的確有助於效率,但這是不夠的。

    作為專業的程式設計師,我們可以開一下腦洞:BIO/NIO/AIO、非同步/同步、阻塞/非阻塞...

    要同時處理那麼多的請求,要知道,有的請求需要發生IO,可能需要很長時間,如果等著它,就會拖慢worker的處理速度。

    Nginx採用了Linux的epoll模型,epoll模型基於事件驅動機制,它可以監控多個事件是否準備完畢,如果OK,那麼放入epoll佇列中,這個過程是非同步的。worker只需要從epoll佇列迴圈處理即可。

    05如何做到熱部署?

    所謂熱部署,就是配置檔案nginx.conf修改後,不需要stop Nginx,不需要中斷請求,就能讓配置檔案生效!(nginx -s reload 重新載入|nginx -t檢查配置|nginx -s stop 停止nginx)

    透過上文我們已經知道worker程序負責處理具體的請求,那麼如果想達到熱部署的效果,可以想象:

    方案一:

    修改配置檔案nginx.conf後,主程序master負責推送給woker程序更新配置資訊,woker程序收到資訊後,更新程序內部的執行緒資訊。(有點valatile的味道)

    方案二:

    修改配置檔案nginx.conf後,重新生成新的worker程序,當然會以新的配置進行處理請求,而且新的請求必須都交給新的worker程序,至於老的worker程序,等把那些以前的請求處理完畢後,kill掉即可。

    Nginx採用的就是方案二來達到熱部署的!

    模擬一個例子:

    首先在本地模擬一個線上需要升級 Nginx 的環境,假設舊版本為 nginx-1.0.15,需要升級到 nginx-1.16.0。

    開始之前,先牢記一下以下幾個命令:

    -HUP 平滑啟動(相當於reload)

    -USR2 平滑升級可執行程式,主要用在版本升級

    -WINCH 從容關閉工作程序

    -USR1 重新開啟日誌檔案,主要用在日誌切割(相當於reopen)

    配置舊版本

    # 下載 nginx-1.0.15

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

    # 解壓壓縮包

    tar -zxf nginx-1.0.15.tar.gz

    # 進入解壓後的目錄

    cd nginx-1.0.15

    # 配置 nginx

    ./configure --prefix=/home/nginx

    # 編譯安裝

    make && make install

    # 執行 nginx

    sudo /home/nginx/sbin/nginx

    獲得新版本二進位制

    # 下載 nginx-1.16.0

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

    # 解壓壓縮包

    tar -zxf nginx-1.16.0

    # 進入解壓後的目錄

    cd nginx-1.16.0/

    # 配置 nginx

    ./configure --prefix=/home/nginx

    # 只編譯不需要安裝

    make

    在編譯後的 objs 目錄中,可以看到二進位制檔案 nginx。

    熱部署

    經過以上步驟,我們實現了一個正在執行的舊版本 nginx 和編譯完成的新版本 nginx 二進位制執行檔案。

    熱部署的流程是:

    備份舊的 nginx 可執行檔案

    新的 nginx 可執行檔案直接替換舊的(此時舊的 nginx 程序還在執行)

    向 nginx master 程序傳送熱部署訊號,新的 nginx 程序啟動,舊的 worker 不再就收請求。

    關閉舊的 worker 程序,完成熱部署。

    # 備份

    cp /home/nginx/sbin/nginx /home/nginx/sbin/nginx.old

    # 替換

    cp -f objs/nginx /home/nginx/sbin/nginx

    # 檢視 master pid

    ps -ef | grep nginx

    root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx

    nobody 23715 23712 0 21:21 ? 00:00:00 nginx: worker process

    # 傳送熱部署訊號,這裡 master pid 替換為自己查詢到的

    kill -USR2 23712

    # 檢視當前 nginx 程序情況,27522 就是新的 master 程序

    ps -ef | grep nginx

    root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx

    nobody 23715 23712 0 21:21 ? 00:00:00 nginx: worker process

    root 27522 23712 0 21:41 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx

    nobody 27524 27522 0 21:41 ? 00:00:00 nginx: worker process

    # 關閉舊的 worker

    kill -WINCH 23712

    # 再次檢視程序,可以發現舊的worker程序關閉了

    ps -ef | grep nginx

    root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx

    root 27522 23712 0 21:41 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx

    nobody 27524 27522 0 21:41 ? 00:00:00 nginx: worker process

    保留舊的 master 程序是為了在新的版本存在問題時,可以快速回退到原版本。如果發現問題要緊急回滾呢?

    cp -f nginx.old nginx

    # 拉起舊版本的worker程序(-HUP 相當於 -s reload)

    kill -HUP old_master_pid

    # 讓新版本的 worker 不再接受請求

    kill -USR2 new_master_pid

    # 關閉新版本的 woker 程序

    kill -WINCH new_master_pid

    如果確認無誤要退出老版本的 nginx,可以執行命令

    kill -QUIT old_master_pid

  • 中秋節和大豐收的關聯?
  • 諸葛亮有沒有後代呢?