【Nginx學習筆記】-初識Nginx
阿新 • • 發佈:2021-01-12
[TOC]
Nginx中文文件 - https://www.nginx.cn/doc/
Nginx ("engine x") 是一個高效能的 HTTP 和 反向代理 伺服器,也是一個 IMAP/POP3/SMTP 代理伺服器。 Nginx 是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開發的,第一個公開版本0.1.0釋出於2004年10月4日。其將原始碼以類BSD許可證的形式釋出,因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。
Nginx 解決了伺服器的C10K(就是在一秒之內連線客戶端的數目為10k即1萬)問題。它的設計不像傳統的伺服器那樣使用執行緒處理請求,而是一個更加高階的機制—`事件驅動機制`,是一種非同步事件驅動結構。它可以輕鬆在百萬併發連線下實現高吞吐量的Web服務,同時諸多應用場景下的問題都可以通過種種Nginx模組得以解決,而我們所需的工作量也並不大
![](https://gitee.com/owen2016/pic-hub/raw/master/1610378133_20200624150926016_509393060.png)
## Nginx 特點
- 高併發請求的同時保持高效的服務
- 熱部署
- 低記憶體消耗/很高的可靠性
- 處理響應請求很快
- 非阻塞、高併發連線-IO多路複用epoll(IO複用)
- 輕量級
- 功能模組少 - Nginx僅保留了HTTP需要的模組,其他都用外掛的方式,後天新增
- 程式碼模組化 - 更適合二次開發,如阿里巴巴Tengine
- CPU親和
- 把CPU核心和Nginx工作程序繫結,把每個worker程序固定在一個CPU上執行,減少切換CPU的cache miss,從而提高效能。
- Nginx接收使用者請求是非同步的,即先將使用者請求全部接收下來,再一次性發送到後端Web伺服器,極大減輕後端Web伺服器的壓力。
- 支援內建伺服器檢測。Nginx能夠根據應用伺服器處理頁面返回的狀態碼、超時資訊等檢測伺服器是否出現故障,並及時返回錯誤的請求重新提交到其它節點上
- 採用Master/worker多程序工作模式
## Nginx 基本功能
Nginx的功能包括基本HTTP功能和擴充套件功能。和Apache伺服器一樣,Nginx伺服器為了提供更多的功能並且能夠有效地擴充套件這些功能。每一個模組都提供了一個功能,通過編譯這些功能模組來實現功能的擴充套件
1. 基本HTTP功能
a)提供靜態檔案和index檔案,處理靜態檔案,索引檔案以及自動索引,開啟檔案描述符快取;
b)使用快取加速反向代理,反向代理加速(無快取),簡單的負載均衡和容錯;
c)使用快取機制加速遠端FastCGI,簡單的負載均衡和容錯;
d)模組化的結構。過濾器包括gzipping,byte ranges,chunked responses,以及 SSI-filter。在SSI過濾器中,到同一個 proxy 或者 FastCGI 的多個子請求併發處理;
e)支援SSL 和 TLS SNI 支援;
f)IMAP/POP3代理服務功能;
g)使用外部 HTTP 認證伺服器重定向使用者到 IMAP/POP3 後端;
h)使用外部 HTTP 認證伺服器認證使用者後連線重定向到內部的 SMTP 後端;
2. 其他HTTP功能
a)基於名稱和基於IP的虛擬伺服器;
b)支援Keep-alive和管道連線;
c)靈活的配置和重新配置、線上升級的時候不用中斷客戶訪問的處理;
d)訪問日誌的格式,快取日誌寫入和快速日誌輪循;
e)3xx-5xx錯誤程式碼重定向;
f)速度限制
## Nginx 使用場景
- 搭建靜態資源伺服器
- 反向代理分發後端服務(可以和nodejs搭配實現前後端分離)和跨域問題
- 根據User Agent來重定向站點
- 開發環境或測試環境切換(切換host)
- url重寫,使用rewrie規則本地對映
- 資源內容篡改
- 獲取cookie做分流
- 資源合併
- gzip壓縮
- 壓縮圖片
- sourceMap除錯
![](https://cdn.devopsing.site/2020/20210112000306.jpeg)
## Nginx 安裝/解除安裝
下載地址:http://nginx.org/en/download.html
### Docker 方式執行
`docker run --name nginx -p 8080:80 -d nginx`
### Ubuntu上安裝
- http://nginx.org/en/linux_packages.html#Ubuntu
``` shell
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:nginx/stable
sudo apt-get update
sudo apt-get install nginx
```
安裝完成後,檢查Nginx服務的狀態`sudo systemctl status nginx` 和 版本`nginx -V`
訪問:http://localhost
![](https://cdn.devopsing.site/2020/20210112000843.png)
啟動時候若顯示埠80被佔用: `Starting nginx: [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use),`
修改檔案:/etc/nginx/sites-available/default,把 listen 後面的 80 埠號改為自己的埠,訪問是需要新增埠號。
安裝完後如出現403錯誤,那可能是nginx配置檔案裡的網站路徑不正確
### 解除安裝Nginx
``` shell
sudo apt-get remove nginx nginx-common # 解除安裝刪除除了配置檔案以外的所有檔案。
sudo apt-get purge nginx nginx-common # 解除安裝所有東東,包括刪除配置檔案。
sudo apt-get autoremove # 在上面命令結束後執行,主要是解除安裝刪除Nginx的不再被使用的依賴包。
sudo apt-get remove nginx-full nginx-common #解除安裝刪除兩個主要的包。
```
## Nginx 命令
```shell
- sudo nginx #開啟 nginx
- nginx -s reload|reopen|stop|quit #重新載入配置|重啟|停止|退出 nginx
- nginx -t #測試配置是否有語法錯誤
nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]
-?,-h : 開啟幫助資訊
-v : 顯示版本資訊並退出
-V : 顯示版本和配置選項資訊,然後退出
-t : 檢測配置檔案是否有語法錯誤,然後退出
-q : 在檢測配置檔案期間遮蔽非錯誤資訊
-s signal : 給一個 nginx 主程序傳送訊號:stop(停止), quit(退出), reopen(重啟), reload(重新載入配置檔案)
-p prefix : 設定字首路徑(預設是:/usr/local/Cellar/nginx/1.2.6/)
-c filename : 設定配置檔案(預設是:/usr/local/etc/nginx/nginx.conf)
-g directives : 設定配置檔案外的全域性指令
```
驗證配置是否正確: nginx -t
配置檔案修改重灌載命令:nginx -s reload
停止nginx: `sudo systemctl stop nginx`
啟動nginx: `sudo systemctl start nginx`
預設,nginx是隨著系統啟動的時候自動執行,`sudo systemctl disable nginx`可以禁止nginx開機啟動.
重新配置nginx開機自動啟動: `sudo systemctl enable nginx`
重啟nginx: `sudo systemctl restart nginx`
平滑載入配置(不會斷開使用者訪問):`sudo systemctl reload nginx`
- reload,重新載入的意思,reload會重新載入配置檔案,nginx服務不會中斷,而且reload時會測試conf語法等,如果出錯會rollback用上一次正確配置檔案保持正常執行。
- restart,重啟,會重啟nginx服務。這個重啟會造成服務一瞬間的中斷,當然如果配置檔案出錯會導致服務啟動失敗,那就是更長時間的服務中斷了。
## Nginx 目錄結構
網站檔案位置
- /var/www/html: 網站檔案存放的地方, 預設只有我們上面看到nginx頁面,可以通過改變nginx配置檔案的方式來修改這個位置。
伺服器配置
- /etc/nginx: nginx配置檔案目錄。所有的nginx配置檔案都在這裡。
- /etc/nginx/nginx.conf: Nginx的主配置檔案. 可以修改他來改變nginx的全域性配置。
- /etc/nginx/sites-available/: 這個目錄儲存每一個網站的"server blocks"。nginx通常不會使用這些配置,除非它們陪連線到 sites-enabled 目錄 (see below)。一般所有的server block 配置都在這個目錄中設定,然後軟連線到別的目錄 。
- /etc/nginx/sites-enabled/: 這個目錄儲存生效的 "server blocks" 配置. 通常,這個配置都是連結到 sites-available目錄中的配置檔案
- /etc/nginx/snippets: 這個目錄主要可以包含在其它nginx配置檔案中的配置片段。重複的配置都可以重構為配置片段。
日誌檔案
- /var/log/nginx/access.log: 每一個訪問請求都會記錄在這個檔案中,除非你做了其它設定
- /var/log/nginx/error.log: 任何Nginx的錯誤資訊都會記錄到這個檔案中
## Nginx熱部署
所謂熱部署,就是配置檔案nginx.conf修改後,不需要stop Nginx,不需要中斷請求,就能讓配置檔案生效!(nginx -s reload 重新載入/nginx -t檢查配置/nginx -s stop)
通過上文我們已經知道worker程序負責處理具體的請求,那麼如果想達到熱部署的效果,可以想象:
**方案一:** 修改配置檔案nginx.conf後,主程序master負責推送給woker程序更新配置資訊,woker程序收到資訊後,更新程序內部的執行緒資訊。(有點valatile的味道)
**方案二:** 修改配置檔案nginx.conf後,重新生成新的worker程序,當然會以新的配置進行處理請求,而且新的請求必須都交給新的worker程序,至於老的worker程序,等把那些以前的請求處理完畢後,kill掉即可。
Nginx採用的就是方案二來達到熱部署的!
## Nginx 執行原理
### Master-Worker模式
![](https://gitee.com/owen2016/pic-hub/raw/master/1610378134_20200624162443069_232260949.png)
啟動Nginx後,其實就是在80埠啟動了Socket服務進行監聽,如圖所示,Nginx涉及Master程序和Worker程序
![](https://gitee.com/owen2016/pic-hub/raw/master/1610378134_20200624162509036_171276403.png)
Master程序的作用是?
- 讀取並驗證配置檔案nginx.conf;管理worker程序;
Worker程序的作用是?
- 每一個Worker程序都維護一個執行緒(避免執行緒切換),處理連線和請求;注意Worker程序的個數由配置檔案決定,一般和CPU個數相關(有利於程序切換),配置幾個就有幾個Worker程序。
首先,Nginx在啟動時,會解析配置檔案,得到需要監聽的埠與IP地址,然後在Nginx的master程序裡面,先初始化好這個監控的socket(建立socket,設定addrreuse等選項,繫結到指定的IP地址埠,再listen),然後再fork(一個現有程序可以呼叫fork函式建立一個新程序。由fork建立的新程序被稱為子程序 )出多個子程序出來,然後子程序會競爭accept新的連線。
此時,客戶端就可以向Nginx發起連線了。當客戶端與Nginx進行三次握手,與Nginx建立好一個連線後,某一個子程序會accept成功,得到這個建立好的連線的socket,然後建立Nginx對連線的封裝,即ngx_connection_t結構體。
接著,設定讀寫事件處理函式並新增讀寫事件來與客戶端進行資料的交換。最後,Nginx或客戶端來主動關掉連線
### Nginx如何做到高併發下的高效處理?
上文已經提及Nginx的worker程序個數與CPU繫結、worker程序內部包含一個執行緒高效迴環處理請求,這的確有助於效率,但這是不夠的。
作為專業的程式設計師,我們可以開一下腦洞:BIO/NIO/AIO、非同步/同步、阻塞/非阻塞...
要同時處理那麼多的請求,要知道,有的請求需要發生IO,可能需要很長時間,如果等著它,就會拖慢worker的處理速度。
Nginx採用了Linux的**epoll模型**,epoll模型基於事件驅動機制,它可以監控多個事件是否準備完畢,如果OK,那麼放入epoll佇列中,這個過程是非同步的。worker只需要從epoll佇列迴圈處理即可。
## Nginx 高可用
Nginx既然作為入口閘道器,很重要,如果出現單點問題,顯然是不可接受的。
答案是:**Keepalived+Nginx**實現高可用。
Keepalived是一個高可用解決方案,主要是用來防止伺服器單點發生故障,可以通過和Nginx配合來實現Web服務的高可用。(其實,Keepalived不僅僅可以和Nginx配合,還可以和很多其他服務配合)
Keepalived+Nginx實現高可用的思路:
第一:請求不要直接打到Nginx上,應該先通過Keepalived(這就是所謂虛擬IP,VIP)
第二:Keepalived應該能監控Nginx的生命狀態(提供一個使用者自定義的指令碼,定期檢查Nginx程序狀態,進行權重變化,,從而實現Nginx故障切換)
![](https://gitee.com/owen2016/pic-hub/raw/master/1610378135_20200624172822781_380420