Web服務器也稱為WWW(WORLD WIDE WEB)服務器,主要功能是提供網上信息浏覽服務。
Web服務器常常以B/S(Browser/Server)方式提供服務。浏覽器和服務器的交互方式如下:
GET /index.php HTTP/1.1
+---------------+ +----------------+
| +-------------------> |
| Browser | | Server |
| <-------------------+ |
+---------------+ +----------------+
HTTP/1.1 200 OK
Apache和Nginx都屬於Web服務器,兩者都實現了HTTP 1.1協議。
Apache HTTP Server是Apache軟件基金會的一個開放源代碼的網頁服務器,可以在大多數計算機操作系統中運行,由於其跨平台和安全性。被廣泛使用,是最流行的 Web服務器端軟件之一。它快速、可靠並且可通過簡單的API擴充,將Perl/Python等解釋器編譯到服務器中。 – 維基百科
Apache是基於模塊化設計的,它的核心代碼並不多,大多數的功能都被分散到各個模塊中,各個模塊在系統啟動的時候按需載入。
+----------+
+- | Module | -----------------+
| +----------+ |
| +------------+
+-----------+ Apache HTTPD | php module |
| Module | +------------+
+-----------+ +----------+|
+----------+-------- | MPM |+
| +----+---+-+
+-v-----------+ | |
| ARP <--+ |
+------+------+ |
| |
+---------------v-------------v--+
| Operating System |
+--------------------------------+
MPM(Multi -Processing Modules,多重處理模塊)是Apache的核心組件之一,Apache通過MPM來使用操作系統的資源,對進程和線程池進行管理。Apache為了能夠獲得最好的運行性能,針對不同的平台 (Unix/Linux、Window)做了優化,為不同的平台提供了不同的MPM,用戶可以根據實際情況進行選擇,其中最常使用的MPM有 prefork和worker兩種。至於您的服務器正以哪種方式運行,取決於安裝Apache過程中指定的MPM編譯參數,在X系統上默認的編譯參數為 prefork。
由於大多數的Unix都不支持真正的線程,所以采用了預派生子進程(prefork)方式,象Windows或者Solaris這些支持 線程的平台,基於多進程多線程混合的worker模式是一種不錯的選擇。Apache中還有一個重要的組件就是APR(Apache portable Runtime Library),即Apache可移植運行庫,它是一個對操作系統調用的抽象庫,用來實現Apache內部組件對操作系統的使用,提高系統的可移植性。 Apache對於php的解析,就是通過眾多Module中的php Module來完成的。
+--------------------------------------------------------------+
| +---------------------+ 啟動階段 |
| | 系統啟動, 配置 | |
| +----------+----------+ |
| | |
| +----------v----------+ |
| | 模塊的初始化 | |
| +-+--------+--------+-+ |
| | | | |
| +-------------+ | +------v-------+| +--------------+ |
| | 子進程初始化 |<+ | 子進程初始化 |+>| 子進程初始化 | |
| +------+------+ +-------+------+ +-------+------+ |
+--------------------------------------------------------------+
| | | | 運行階段 |
| +----v----+ +----v----+ +----v----+ |
| | 請求循環 | | 請求循環 | | 請求循環 | |
| +----+----+ +----+----+ +----+----+ |
| | | | |
| +------v------+ +------v------+ +------v------+ |
| | 子進程結束 | | 子進程結束 | | 子進程結束 | |
| +-------------+ +-------------+ +-------------+ |
+--------------------------------------------------------------+
這個生命周期是在perfork工作下的示意,從圖中可以看出,Apache對於每一個請求都要啟動一個單獨的進程來處理。
一個單獨的控制進程(父進程)負責產生子進程,這些子進程用於監聽請求並作出應答。Apache總是試圖保持一些備用的 (spare)或是空閒的子進程用於迎接即將到來的請求。這樣客戶端就無需在得到服務前等候子進程的產生。在Unix系統中,父進程通常以root身份運行以便邦定80端口,而 Apache產生的子進程通常以一個低特權的用戶運行。User和Group指令用於配置子進程的低特權用戶。運行子進程的用戶必須要對他所服務的內容有讀取的權限,但是對服務內容之外的其他資源必須擁有盡可能少的權限。
每個進程能夠擁有的線程數量是固定的。服務器會根據負載情況增加或減少進程數量。一個單獨的控制進程(父進程)負責子進程的建立。每個子進程能夠建立ThreadsPerChild數量的服務線程和一個監聽線程,該監聽線程監聽接入請求並將其傳遞給服務線程處理和應答。Apache總是試圖維持一個備用(spare)或是空閒的服務線程池。這樣,客戶端無須等待新線程或新進程的建立即可得到處理。在Unix中,為了能夠綁定80端口,父進程一般都是以root身份啟動,隨後,Apache以較低權限的用戶建立子進程和線程。User和Group指令用於配置Apache子進程的權限。雖然子進程必須對其提供的內容擁有讀權限,但應該盡可能給予他較少的特權。另外,除非使用了suexec ,否則,這些指令配置的權限將被CGI腳本所繼承。
在啟動階段,Apache主要進行配置文件解析(例如http.conf以及Include指令設定的配置文件等)、模塊加載(例如 mod_php.so,mod_perl.so等)和系統資源初始化(例如日志文件、共享內存段等)工作。在這個階段,Apache為了獲得系統資源最大的使用權限,將以特權用戶root(X系統)或超級管理員administrator(Windows系統)完成啟動。
這個過程可以通過下圖來深入了解:
+--------+
| 開始 |
+----+---+
|
+----------v------------+ 解析主配置文件http.conf中配置信息,
| 解析配置文件 | 像LoadModule, AddType
+----------+------------+ 等指令被加載至內存
|
+----------v------------+ 依據AddModule, LoadModule等指令
| 加載靜態/動態模塊 | 加載Apache模塊,像mod_php5.so被
+----------+------------+ 加載至內存,映射到Apache地址空間。
|
+----------v------------+ 日志文件、共享內存段,數據庫鏈接
| 系統資源初始化 | 等初始化
+----------+------------+
|
+---v----+
| 結束 |
+--------+
在運行階段,Apache主要工作是處理用戶的服務請求。在這個階段,Apache放棄特權用戶級別,使用普通權限,這主要是基於安全性的考慮,防止由於代碼的缺陷引起的安全漏洞。
由於Apache的Hook機制,Apache 允許模塊(包括內部模塊和外部模塊,例如mod_php5.so
,mod_perl.so
等)將自定義的函數注入到請求處理循環中。mod_php5.so
/php5apache2.dll
就是將所包含的自定義函數,通過Hook機制注入到Apache中,在Apache處理流程的各個階段負責處理php請求。
Apache將請求處理循環分為11個階段,依次是:Post-Read-Request,URI Translation,Header Parsing,Access Control,Authentication,Authorization,MIME Type Checking,FixUp,Response,Logging,CleanUp。
Apache處理http請求的生命周期:
Nginx(發音同engine x)是一款由俄羅斯程序員Igor Sysoev所開發輕量級的網頁服務器、反向代理服務器以及電子郵件(IMAP/POP3)代理服務器。起初是供俄國大型的門戶網站及搜索引擎Rambler(俄語:Рамблер)使用。 – 維基百科
Nginx由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個 location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。
Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊:
Nginx的模塊從功能上分為如下三類:
+ ^
Http Request | | Http Response
| |
+---------+------v-----+ +----+----+
| Conf | Nginx Core | | FilterN |
+---------+------+-----+ +----^----+
| |
| +----+----+
| | Filter2 |
choose a handler | +----^----+
based conf | |
| +----+----+
| | Filter1 |
| +----^----+
| | Generate content
+-----v--------------------+----+
| Handler |
+-------------------------------+
Nginx本身做的工作實際很少,當它接到一個HTTP請求時,它僅僅是通過查找配置文件將此次請求映射到一個location block,而此location中所配置的各個指令則會啟動不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動工作者。通常一個 location中的指令會涉及一個handler模塊和多個filter模塊(當然,多個location可以復用同一個模塊)。handler模塊負責處理請求,完成響應內容的生成,而filter模塊對響應內容進行處理。