1. 程式人生 > >Nginx原理詳解

Nginx原理詳解

ast 反向代理服務器 mut 系列 產生 開源 和我 headers 並且

摘要:1.Nginx模塊和工作原理Nginx由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個locationblock(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊。
?

nginx概述

?
nginx是一款自由的、開源的、高性能的HTTP服務器和反向代理服務器;同時也是一個IMAP、POP3、SMTP代理服務器;nginx可以作為一個HTTP服務器進行網站的發布處理,另外nginx可以作為反向代理進行負載均衡的實現。

?

這裏主要通過三個方面簡單介紹nginx

?
1.nginx模塊和工作原理
Nginx由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。

?
Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊:

?
核心模塊:HTTP模塊、EVENT模塊和MAIL模塊
?

基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,

?

第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。
?

用戶根據自己的需要開發的模塊都屬於第三方模塊。正是有了這麽多模塊的支撐,Nginx的功能才會如此強大。
?

Nginx的模塊從功能上分為如下三類。

?
?
Handlers(處理器模塊)。此類模塊直接處理請求,並進行輸出內容和修改headers信息等操作。Handlers處理器模塊一般只能有一個。
?
?
Filters (過濾器模塊)。此類模塊主要對其他處理器模塊輸出的內容進行修改操作,最後由Nginx輸出。

?
Proxies (代理類模塊)。此類模塊是Nginx的HTTP Upstream之類的模塊,這些模塊主要與後端一些服務比如FastCGI等進行交互,實現服務代理和負載均衡等功能。

?
?
2. Nginx的進程模型
在工作方式上,Nginx分為單工作進程和多工作進程兩種模式。
?
?
在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單線程的;
在多工作進程模式下,每個工作進程包含多個線程。Nginx默認為單工作進程模式。
Nginx在啟動後,會有一個master進程和多個worker進程。
?
?
master進程
主要用來管理worker進程,包含:接收來自外界的信號,向各worker進程發送信號,監控worker進程的運行狀態,當worker進程退出後(異常情況下),會自動重新啟動新的worker進程。
?
?
master進程充當整個進程組與用戶的交互接口,同時對進程進行監護。它不需要處理網絡事件,不負責業務的執行,只會通過管理worker進程來實現重啟服務、平滑升級、更換日誌文件、配置文件實時生效等功能。
?
?
我們要控制nginx,只需要通過kill向master進程發送信號就行了。比如kill -HUP pid,則是告訴nginx,從容地重啟nginx,我們一般用這個信號來重啟nginx,或重新加載配置,因為是從容地重啟,因此服務是不中斷的。master進程在接收到HUP信號後是怎麽做的呢?
?
?
首先master進程在接到信號後,會先重新加載配置文件,然後再啟動新的worker進程,並向所有老的worker進程發送信號,告訴他們可以光榮退休了。
?
?
?

新的worker在啟動後,就開始接收新的請求,而老的worker在收到來自master的信號後,就不再接收新的請求,並且在當前進程中的所有未處理完的請求處理完成後,再退出。
?
?
當然,直接給master進程發送信號,這是比較老的操作方式,nginx在0.8版本之後,引入了一系列命令行參數,來方便我們管理。比如,./nginx -s reload,就是來重啟nginx,./nginx -s stop,就是來停止nginx的運行。如何做到的呢?我們還是拿reload來說,我們看到,執行命令時,我們是啟動一個新的nginx進程,而新的nginx進程在解析到reload參數後,就知道我們的目的是控制nginx來重新加載配置文件了,它會向master進程發送信號,然後接下來的動作,就和我們直接向master進程發送信號一樣了。
?
?
worker進程:
而基本的網絡事件,則是放在worker進程中來處理了。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求,各進程互相之間是獨立的。一個請求,只可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。worker進程的個數是可以設置的,一般我們會設置與機器cpu核數一致,這裏面的原因與nginx的進程模型以及事件處理模型是分不開的。
?
?
worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。當我們提供80端口的http服務時,一個連接請求過來,每個進程都有可能處理這個連接,怎麽做到的呢?
?
?

首先,每個worker進程都是從master進程fork過來,在master進程裏面,先建立好需要listen的socket(listenfd)之後,然後再fork出多個worker進程。所有worker進程的listenfd會在新連接到來時變得可讀,為保證只有一個進程處理該連接,所有worker進程在註冊listenfd讀事件前搶accept_mutex,搶到互斥鎖的那個進程註冊listenfd讀事件,在讀事件裏調用accept接受該連接。
?
?
當一個worker進程在accept這個連接之後,就開始讀取請求,解析請求,處理請求,產生數據後,再返回給客戶端,最後才斷開連接,這樣一個完整的請求就是這樣的了。
?
?
我們可以看到,一個請求,完全由worker進程來處理,而且只在一個worker進程中處理。

Nginx原理詳解