Nginx 的應用場景主要有三個:
- 靜态資源服務
- 反向代理服務
- API 服務
靜态資源服務
Nginx 可以通過本地文件系統提供靜态資源的服務,例如純靜态的 HTML 頁面等。
反向代理服務
很多應用服務的運行效率是很低的,QPS,TPS,并發等都是受限的,所以需要把很多應用服務組成一個集群,向用戶提供高可用性的服務,這個時候需要 Nginx 的反向代理功能,而應用服務的動态擴容需要負載均衡功能,另外一個,Nginx 層還需要做緩存。因此反向代理服務主要是三個功能:
- 反向代理
- 負載均衡
- 緩存
API 服務
有時候應用服務本身有很多性能問題,但是數據庫服務要比應用服務好的多,業務場景比較簡單,并發性和 TPS 都要遠高于應用服務,所以這個時候可以由 Nginx 直接去訪問數據庫或者 Redis,還可以利用 Nginx 的強大的并發性來實現應用防火牆的 API 服務。
Nginx 架構基礎Nginx 狀态機
Nginx 對外提供服務時,主要有三種流量會到達 Nginx:WEB、EMAIL、TCP 流量。這三種流量到達 Nginx 後,會分别由傳輸層狀态機、應用層狀态機、MAIL 狀态機來處理。當内存不足以緩存所有的靜态資源時,會退化成阻塞的磁盤調用,這個時候需要一個線程池來處理,對于每一個處理完的請求記錄訪問日志和錯誤日志,日志也是記錄到磁盤中的。
Nginx 的進程結構
Nginx 有四種進程:
- Master 進程。Master 進程是父進程,其他進程都是子進程,Master 進程對 worker 進程進行管理
- worker 進程。worker 進程有多個,是負責處理具體的請求的。Nginx 為什麼采用多進程而不是多線程的進程結構呢?是因為 Nginx 要保證高可用性,多線程之間會共享地址空間,當某一個第三方模塊引發了一個段錯誤時,就會導緻整個 Nginx 進程挂掉。而采用多進程模型不會出現這個問題
- cache manager 和 cache loader 進程。緩存除了要被多個 worker 進程使用,也要被 cache 進程使用,cache loader 做緩存的載入,cache manager 做緩存的管理,實際上每一個請求所使用的緩存還是由 worker 進程來進行的。這些進程間的通信都是通過共享内存來進行的
為什麼 worker 進程需要很多個?
這是因為,Nginx 采用了事件驅動的模型後,它期望 worker 進程可以從頭到尾占滿一顆 CPU,這樣可以更加高效的利用整顆 CPU,提高 CPU 的緩存命中率,另外還可以将 worker 進程與某一個 CPU 核綁定在一起。
使用信号管理 Nginx 的父子進程
在前面說到了 Nginx 的命令行,其實很多 Nginx 的信号都是通過向 master 進程發送信号來實現的。
Master 進程
master 進程會監控 worker 進程,而監控是通過 Linux 規定的當子進程退出時需要向父進程發送 CHLD 信号實現的。這樣可以當出現 bug 時,立刻拉起 worker。
master 進程可以接收以下信号:
- TERM, INT
- QUIT
- HUP
- USR1
- USR2
- WINCH
Worker 進程
worker 進程可以接收以下信号:
- TERM, INT
- QUIT
- HUP
- USR1
- WINCH
命令行對應的信号
- reload:HUP
- reopen:USR1
- stop:TERM
- quit:QUIT
USR2 和 WINCH 沒有對應的信号,隻能通過 kill 發送。
stop 和 quit 的區别是,一個是立即退出,一個是優雅的停止。
reload 重載配置文件的真相
- 向 master 進程發送 HUP 信号
- master 進程檢查配置文件是否有語法問題
- master 進程打開新的監聽端口(如果配置了新的端口)
- master 進程使用新的配置文件啟動 worker 進程
- master 進程向老的 worker 進程發送 QUIT 信号
- 老 worker 進程關閉監聽句柄,處理完當前連接後結束進程
熱部署的真相
在上一篇文章中,講了熱部署的流程,那麼熱部署具體的流程是怎麼樣的呢?
- 将舊的 Nginx 文件替換成新的 Nginx 文件(注意備份)
- 向 master 進程發送 USR2 信号
- master 進程修改 pid 文件名,加後綴 .oldbin
- master 進程用新 Nginx 文件啟動新 master 進程
- 向老的 master 進程發送 quit 信号,關閉老的 master
- 回滾操作,向老的 master 進程發送 HUP 信号,向新的 master 發 QUIT
優雅的關閉 worker 進程
- 設置定時器 worker_shutdown_timeout
- 關閉監聽句柄
- 關閉空閑連接
- 再循環等待全部連接關閉
- 退出進程
這裡面,定時器的作用是,如果時間超時了,但是連接還沒有處理完畢,就會強制退出進程。另外,Nginx 隻能處理 HTTP 的優雅關閉,websocket 、TCP、UDP 的代理都做不到,worker 不解析數據。
以上這些内容,就是 Nginx 命令行和信号的完整過程。下一講開始講 HTTP 模塊。
,