1.Web服務(wù)器
Web服務(wù)器也稱(chēng)為WWW(WORLD WIDE WEB)服務(wù)器,主要功能是提供網(wǎng)上信息瀏覽服務(wù)。
應用層使用HTTP協(xié)議。
HTML文檔格式。
瀏覽器統一資源定位器(URL)。
Web服務(wù)器常常以B/S(Browser/Server)方式提供服務(wù)。瀏覽器和服務(wù)器的交互方式如下:
GET /index.php HTTP/1.1
+---------------+ +----------------+
| +-------------------> |
| Browser | | Server |
| <-------------------+ |
+---------------+ +----------------+
HTTP/1.1 200 OK
瀏覽器向服務(wù)器發(fā)出HTTP請求(Request)。
服務(wù)器收到瀏覽器的請求數據,經(jīng)過(guò)分析處理,向瀏覽器輸出響應數據(Response)。
瀏覽器收到服務(wù)器的響應數據,經(jīng)過(guò)分析處理,將最終結果顯示在瀏覽器中。
Apache和Nginx都屬于Web服務(wù)器,兩者都實(shí)現了HTTP 1.1協(xié)議。
2.Apache
Apache 概述
Apache HTTP Server是Apache軟件基金會(huì )的一個(gè)開(kāi)放源代碼的網(wǎng)頁(yè)服務(wù)器,可以在大多數計算機操作系統中運行,由于其跨平臺和安全性。被廣泛使用,是最流行的Web服務(wù)器端軟件之一。它快速、可靠并且可通過(guò)簡(jiǎn)單的API擴充,將Perl/Python等解釋器編譯到服務(wù)器中。 -- 維基百科
Apache組件
Apache是基于模塊化設計的,它的核心代碼并不多,大多數的功能都被分散到各個(gè)模塊中,各個(gè)模塊在系統啟動(dòng)的時(shí)候按需載入。
"text"> +----------+
+- | Module | -----------------+
| +----------+ |
| +------------+
+-----------+ Apache HTTPD | php module |
| Module | +------------+
+-----------+ +----------+|
+----------+-------- | MPM |+
| +----+---+-+
+-v-----------+ | |
| ARP <--+ |
+------+------+ |
| |
+---------------v-------------v--+
| Operating System |
+--------------------------------+
MPM(Multi -Processing Modules,多重處理模塊)是Apache的核心組件之一,Apache通過(guò)MPM來(lái)使用操作系統的資源,對進(jìn)程和線(xiàn)程池進(jìn)行管理。Apache為了能夠獲得最好的運行性能,針對不同的平臺 (Unix/Linux、Window)做了優(yōu)化,為不同的平臺提供了不同的MPM,用戶(hù)可以根據實(shí)際情況進(jìn)行選擇,其中最常使用的MPM有 prefork和worker兩種。至于您的服務(wù)器正以哪種方式運行,取決于安裝Apache過(guò)程中指定的MPM編譯參數,在X系統上默認的編譯參數為 prefork。
由于大多數的Unix都不支持真正的線(xiàn)程,所以采用了預派生子進(jìn)程(prefork)方式,象Windows或者Solaris這些支持 線(xiàn)程的平臺,基于多進(jìn)程多線(xiàn)程混合的worker模式是一種不錯的選擇。Apache中還有一個(gè)重要的組件就是APR(Apache portable Runtime Library),即Apache可移植運行庫,它是一個(gè)對操作系統調用的抽象庫,用來(lái)實(shí)現Apache內部組件對操作系統的使用,提高系統的可移植性。 Apache對于php的解析,就是通過(guò)眾多Module中的php Module來(lái)完成的。
Apache生命周期
"text"> +--------------------------------------------------------------+
| +---------------------+ 啟動(dòng)階段 |
| | 系統啟動(dòng), 配置 | |
| +----------+----------+ |
| | |
| +----------v----------+ |
| | 模塊的初始化 | |
| +-+--------+--------+-+ |
| | | | |
| +-------------+ | +------v-------+| +--------------+ |
| | 子進(jìn)程初始化 |<+ | 子進(jìn)程初始化 |+>| 子進(jìn)程初始化 | |
| +------+------+ +-------+------+ +-------+------+ |
+--------------------------------------------------------------+
| | | | 運行階段 |
| +----v----+ +----v----+ +----v----+ |
| | 請求循環(huán) | | 請求循環(huán) | | 請求循環(huán) | |
| +----+----+ +----+----+ +----+----+ |
| | | | |
| +------v------+ +------v------+ +------v------+ |
| | 子進(jìn)程結束 | | 子進(jìn)程結束 | | 子進(jìn)程結束 | |
| +-------------+ +-------------+ +-------------+ |
+--------------------------------------------------------------+
這個(gè)生命周期是在perfork工作下的示意,從圖中可以看出,Apache對于每一個(gè)請求都要啟動(dòng)一個(gè)單獨的進(jìn)程來(lái)處理。
Apache的工作模式 prefork的工作原理
一個(gè)單獨的控制進(jìn)程(父進(jìn)程)負責產(chǎn)生子進(jìn)程,這些子進(jìn)程用于監聽(tīng)請求并作出應答。Apache總是試圖保持一些備用的 (spare)或是空閑的子進(jìn)程用于迎接即將到來(lái)的請求。這樣客戶(hù)端就無(wú)需在得到服務(wù)前等候子進(jìn)程的產(chǎn)生。在Unix系統中,父進(jìn)程通常以root身份運行以便邦定80端口,而 Apache產(chǎn)生的子進(jìn)程通常以一個(gè)低特權的用戶(hù)運行。User和Group指令用于配置子進(jìn)程的低特權用戶(hù)。運行子進(jìn)程的用戶(hù)必須要對他所服務(wù)的內容有讀取的權限,但是對服務(wù)內容之外的其他資源必須擁有盡可能少的權限。
worker的工作原理
每個(gè)進(jìn)程能夠擁有的線(xiàn)程數量是固定的。服務(wù)器會(huì )根據負載情況增加或減少進(jìn)程數量。一個(gè)單獨的控制進(jìn)程(父進(jìn)程)負責子進(jìn)程的建立。每個(gè)子進(jìn)程能夠建立ThreadsPerChild數量的服務(wù)線(xiàn)程和一個(gè)監聽(tīng)線(xiàn)程,該監聽(tīng)線(xiàn)程監聽(tīng)接入請求并將其傳遞給服務(wù)線(xiàn)程處理和應答。Apache總是試圖維持一個(gè)備用(spare)或是空閑的服務(wù)線(xiàn)程池。這樣,客戶(hù)端無(wú)須等待新線(xiàn)程或新進(jìn)程的建立即可得到處理。在Unix中,為了能夠綁定80端口,父進(jìn)程一般都是以root身份啟動(dòng),隨后,Apache以較低權限的用戶(hù)建立子進(jìn)程和線(xiàn)程。User和Group指令用于配置Apache子進(jìn)程的權限。雖然子進(jìn)程必須對其提供的內容擁有讀權限,但應該盡可能給予他較少的特權。另外,除非使用了suexec ,否則,這些指令配置的權限將被CGI腳本所繼承。
Apache的運行 啟動(dòng)階段
在啟動(dòng)階段,Apache主要進(jìn)行配置文件解析(例如http.conf以及Include指令設定的配置文件等)、模塊加載(例如modphp.so,modperl.so等)和系統資源初始化(例如日志文件、共享內存段等)工作。在這個(gè)階段,Apache為了獲得系統資源最大的使用權限,將以特權用戶(hù)root(X系統)或超級管理員administrator(Windows系統)完成啟動(dòng)。
這個(gè)過(guò)程可以通過(guò)下圖來(lái)深入了解:
"text"> +--------+
| 開(kāi)始 |
+----+---+
|
+----------v------------+ 解析主配置文件http.conf中配置信息,
| 解析配置文件 | 像LoadModule, AddType
+----------+------------+ 等指令被加載至內存
|
+----------v------------+ 依據AddModule, LoadModule等指令
| 加載靜態(tài)/動(dòng)態(tài)模塊 | 加載Apache模塊,像mod_php5.so被
+----------+------------+ 加載至內存,映射到Apache地址空間。
|
+----------v------------+ 日志文件、共享內存段,數據庫鏈接
| 系統資源初始化 | 等初始化
+----------+------------+
|
+---v----+
| 結束 |
+--------+
運行階段
在運行階段,Apache主要工作是處理用戶(hù)的服務(wù)請求。在這個(gè)階段,Apache放棄特權用戶(hù)級別,使用普通權限,這主要是基于安全性的考慮,防止由于代碼的缺陷引起的安全漏洞。
由于A(yíng)pache的Hook機制,Apache 允許模塊(包括內部模塊和外部模塊,例如mod_php5.so,mod_perl.so等)將自定義的函數注入到請求處理循環(huán)中。mod_php5.so/php5apache2.dll就是將所包含的自定義函數,通過(guò)Hook機制注入到Apache中,在A(yíng)pache處理流程的各個(gè)階段負責處理php請求。
Apache將請求處理循環(huán)分為11個(gè)階段,依次是:Post-Read-Request,URI Translation,Header Parsing,Access Control,Authentication,Authorization,MIME Type Checking,FixUp,Response,Logging,CleanUp。
Apache處理http請求的生命周期:
Apache處理http請求的生命周期
Post-Read-Request階段:在正常請求處理流程中,這是模塊可以插入鉤子的第一個(gè)階段。對于那些想很早進(jìn)入處理請求的模塊來(lái)說(shuō),這個(gè)階段可以被利用。
URI Translation階段 : Apache在本階段的主要工作:將請求的URL映射到本地文件系統。模塊可以在這階段插入鉤子,執行自己的映射邏輯。mod_alias就是利用這個(gè)階段工作的。
Header Parsing階段 : Apache在本階段的主要工作:檢查請求的頭部。由于模塊可以在請求處理流程的任何一個(gè)點(diǎn)上執行檢查請求頭部的任務(wù),因此這個(gè)鉤子很少被使用。mod_setenvif就是利用這個(gè)階段工作的。
Access Control階段 : Apache在本階段的主要工作:根據配置文件檢查是否允許訪(fǎng)問(wèn)請求的資源。Apache的標準邏輯實(shí)現了允許和拒絕指令。modauthzhost就是利用這個(gè)階段工作的。
Authentication階段 : Apache在本階段的主要工作:按照配置文件設定的策略對用戶(hù)進(jìn)行認證,并設定用戶(hù)名區域。模塊可以在這階段插入鉤子,實(shí)現一個(gè)認證方法。
Authorization階段 : Apache在本階段的主要工作:根據配置文件檢查是否允許認證過(guò)的用戶(hù)執行請求的操作。模塊可以在這階段插入鉤子,實(shí)現一個(gè)用戶(hù)權限管理的方法。
MIME Type Checking階段 : Apache在本階段的主要工作:根據請求資源的MIME類(lèi)型的相關(guān)規則,判定將要使用的內容處理函數。標準模塊modnegotiation和modmime實(shí)現了這個(gè)鉤子。
FixUp階段 : 這是一個(gè)通用的階段,允許模塊在內容生成器之前,運行任何必要的處理流程。和PostReadRequest類(lèi)似,這是一個(gè)能夠捕獲任何信息的鉤子,也是最常使用的鉤子。
Response階段 : Apache在本階段的主要工作:生成返回客戶(hù)端的內容,負責給客戶(hù)端發(fā)送一個(gè)恰當的回復。這個(gè)階段是整個(gè)處理流程的核心部分。
Logging階段 : Apache在本階段的主要工作:在回復已經(jīng)發(fā)送給客戶(hù)端之后記錄事務(wù)。模塊可能修改或者替換Apache的標準日志記錄。
CleanUp階段 : Apache在本階段的主要工作:清理本次請求事務(wù)處理完成之后遺留的環(huán)境,比如文件、目錄的處理或者Socket的關(guān)閉等等,這是Apache一次請求處理的最后一個(gè)階段。
3.Nginx
Nginx 概述
Nginx(發(fā)音同engine x)是一款由俄羅斯程序員Igor Sysoev所開(kāi)發(fā)輕量級的網(wǎng)頁(yè)服務(wù)器、反向代理服務(wù)器以及電子郵件(IMAP/POP3)代理服務(wù)器。起初是供俄國大型的門(mén)戶(hù)網(wǎng)站及搜索引擎Rambler(俄語(yǔ):Рамблер)使用。
Nginx的模塊與工作原理
Nginx由內核和模塊組成,其中,內核的設計非常微小和簡(jiǎn)潔,完成的工作也非常簡(jiǎn)單,僅僅通過(guò)查找配置文件將客戶(hù)端請求映射到一個(gè)location block(location是Nginx配置中的一個(gè)指令,用于URL匹配),而在這個(gè)location中所配置的每個(gè)指令將會(huì )啟動(dòng)不同的模塊去完成相應的工作。
Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊:
核心模塊:HTTP模塊、EVENT模塊和MAIL模塊
基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,
第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。
Nginx的模塊從功能上分為如下三類(lèi):
Handlers(處理器模塊)。此類(lèi)模塊直接處理請求,并進(jìn)行輸出內容和修改headers信息等操作。Handlers處理器模塊一般只能有一個(gè)。
Filters (過(guò)濾器模塊)。此類(lèi)模塊主要對其他處理器模塊輸出的內容進(jìn)行修改操作,最后由Nginx輸出。
Proxies (代理類(lèi)模塊)。此類(lèi)模塊是Nginx的HTTP Upstream之類(lèi)的模塊,這些模塊主要與后端一些服務(wù)比如FastCGI等進(jìn)行交互,實(shí)現服務(wù)代理和負載均衡等功能。
"text"> + ^
Http Request | | Http Response
| |
+---------+------v-----+ +----+----+
| Conf | Nginx Core | | FilterN |
+---------+------+-----+ +----^----+
| |
| +----+----+
| | Filter2 |
choose a handler | +----^----+
based conf | |
| +----+----+
| | Filter1 |
| +----^----+
| | Generate content
+-----v--------------------+----+
| Handler |
+-------------------------------+
Nginx本身做的工作實(shí)際很少,當它接到一個(gè)HTTP請求時(shí),它僅僅是通過(guò)查找配置文件將此次請求映射到一個(gè)location block,而此location中所配置的各個(gè)指令則會(huì )啟動(dòng)不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動(dòng)工作者。通常一個(gè)location中的指令會(huì )涉及一個(gè)handler模塊和多個(gè)filter模塊(當然,多個(gè)location可以復用同一個(gè)模塊)。handler模塊負責處理請求,完成響應內容的生成,而filter模塊對響應內容進(jìn)行處理。
Nginx架構及工作流程
Nginx架構
上圖是Nginx的架構,這個(gè)架構類(lèi)似于A(yíng)pache的Worker工作狀態(tài),Nginx的每一個(gè)Worker進(jìn)程都管理著(zhù)大量的線(xiàn)程,真正處理請求的是Worker之下的線(xiàn)程。
所有實(shí)際上的業(yè)務(wù)處理邏輯都在worker進(jìn)程。worker進(jìn)程中有一個(gè)函數,執行無(wú)限循環(huán),不斷處理收到的來(lái)自客戶(hù)端的請求,并進(jìn)行處理,直到整個(gè)nginx服務(wù)被停止。Worker中這個(gè)函數執行內容如下:
操作系統提供的機制(例如epoll, kqueue等)產(chǎn)生相關(guān)的事件。
接收和處理這些事件,如是接受到數據,則產(chǎn)生更高層的request對象。
處理request的header和body。
產(chǎn)生響應,并發(fā)送回客戶(hù)端。
完成request的處理。
重新初始化定時(shí)器及其他事件。
Nginx和FastCGI FastCGI
FastCGI是一個(gè)可伸縮地、高速地在HTTP server和動(dòng)態(tài)腳本語(yǔ)言間通信的接口。多數流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等。同時(shí),FastCGI也被許多腳本語(yǔ)言支持,其中就有PHP。
FastCGI是從CGI發(fā)展改進(jìn)而來(lái)的。傳統CGI接口方式的主要缺點(diǎn)是性能很差,因為每次HTTP服務(wù)器遇到動(dòng)態(tài)程序時(shí)都需要重新啟動(dòng)腳本解析器來(lái)執行解析,然后將結果返回給HTTP服務(wù)器。這在處理高并發(fā)訪(fǎng)問(wèn)時(shí)幾乎是不可用的。另外傳統的CGI接口方式安全性也很差,現在已經(jīng)很少使用了。
FastCGI接口方式采用C/S結構,可以將HTTP服務(wù)器和腳本解析服務(wù)器分開(kāi),同時(shí)在腳本解析服務(wù)器上啟動(dòng)一個(gè)或者多個(gè)腳本解析守護進(jìn)程。當HTTP服務(wù)器每次遇到動(dòng)態(tài)程序時(shí),可以將其直接交付給FastCGI進(jìn)程來(lái)執行,然后將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務(wù)器專(zhuān)一地處理靜態(tài)請求或者將動(dòng)態(tài)腳本服務(wù)器的結果返回給客戶(hù)端,這在很大程度上提高了整個(gè)應用系統的性能。
Nging和FastCGI合作
Nginx不支持對外部程序的直接調用或者解析,所有的外部程序(包括PHP)必須通過(guò)FastCGI接口來(lái)調用。FastCGI接口在Linux下是socket(這個(gè)socket可以是文件socket,也可以是ip socket)。
接下來(lái)以Nginx下PHP的運行過(guò)程來(lái)說(shuō)明。PHP-FPM是管理FastCGI的一個(gè)管理器,它作為PHP的插件存在。
FastCGI進(jìn)程管理器php-fpm自身初始化,啟動(dòng)主進(jìn)程php-fpm和啟動(dòng)start_servers個(gè)CGI 子進(jìn)程。主進(jìn)程php-fpm主要是管理fastcgi子進(jìn)程,監聽(tīng)9000端口。fastcgi子進(jìn)程等待來(lái)自Web Server的連接。
當客戶(hù)端請求到達Web Server Nginx是時(shí),Nginx通過(guò)location指令,將所有以php為后綴的文件都交給127.0.0.1:9000來(lái)處理,即Nginx通過(guò)location指令,將所有以php為后綴的文件都交給127.0.0.1:9000來(lái)處理。
FastCGI進(jìn)程管理器PHP-FPM選擇并連接到一個(gè)子進(jìn)程CGI解釋器。Web server將CGI環(huán)境變量和標準輸入發(fā)送到FastCGI子進(jìn)程。
FastCGI子進(jìn)程完成處理后將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進(jìn)程關(guān)閉連接時(shí),請求便告處理完成。
FastCGI子進(jìn)程接著(zhù)等待并處理來(lái)自FastCGI進(jìn)程管理器(運行在 WebServer中)的下一個(gè)連接。
Apache和Nginx比較 功能對比
Nginx和Apache一樣,都是HTTP服務(wù)器軟件,在功能實(shí)現上都采用模塊化結構設計,都支持通用的語(yǔ)言接口,如PHP、Perl、Python等,同時(shí)還支持正向和反向代理、虛擬主機、URL重寫(xiě)、壓縮傳輸、SSL加密傳輸等。
在功能實(shí)現上,Apache的所有模塊都支持動(dòng)、靜態(tài)編譯,而Nginx模塊都是靜態(tài)編譯的,
對FastCGI的支持,Apache對Fcgi的支持不好,而Nginx對Fcgi的支持非常好;
在處理連接方式上,Nginx支持epoll,而Apache卻不支持;
在空間使用上,Nginx安裝包僅僅只有幾百K,和Nginx比起來(lái)Apache絕對是龐然大物。
Nginx相對apache的優(yōu)點(diǎn)
輕量級,同樣起web 服務(wù),比apache 占用更少的內存及資源
靜態(tài)處理,Nginx 靜態(tài)處理性能比 Apache 高 3倍以上
抗并發(fā),nginx 處理請求是異步非阻塞的,而apache則是阻塞型的,在高并發(fā)下nginx 能保持低資源低消耗高性能。在A(yíng)pache+PHP(prefork)模式下,如果PHP處理慢或者前端壓力很大的情況下,很容易出現Apache進(jìn)程數飆升,從而拒絕服務(wù)的現象。
高度模塊化的設計,編寫(xiě)模塊相對簡(jiǎn)單
社區活躍,各種高性能模塊出品迅速啊
apache相對nginx的優(yōu)點(diǎn)
rewrite,比nginx 的rewrite 強大
模塊超多,基本想到的都可以找到
少bug,nginx的bug相對較多
超穩定
Apache對PHP支持比較簡(jiǎn)單,Nginx需要配合其他后端用
選擇Nginx的優(yōu)勢所在
作為Web服務(wù)器: Nginx處理靜態(tài)文件、索引文件,自動(dòng)索引的效率非常高。
作為代理服務(wù)器,Nginx可以實(shí)現無(wú)緩存的反向代理加速,提高網(wǎng)站運行速度。
作為負載均衡服務(wù)器,Nginx既可以在內部直接支持Rails和PHP,也可以支持HTTP代理服務(wù)器對外進(jìn)行服務(wù),同時(shí)還支持簡(jiǎn)單的容錯和利用算法進(jìn)行負載均衡。
在性能方面,Nginx是專(zhuān)門(mén)為性能優(yōu)化而開(kāi)發(fā)的,在實(shí)現上非常注重效率。它采用內核Poll模型(epoll and kqueue ),可以支持更多的并發(fā)連接,最大可以支持對50 000個(gè)并發(fā)連接數的響應,而且只占用很低的內存資源。
在穩定性方面,Nginx采取了分階段資源分配技術(shù),使得CPU與內存的占用率非常低。Nginx官方表示,Nginx保持10 000個(gè)沒(méi)有活動(dòng)的連接,而這些連接只占用2.5MB內存,因此,類(lèi)似DOS這樣的攻擊對Nginx來(lái)說(shuō)基本上是沒(méi)有任何作用的。
在高可用性方面,Nginx支持熱部署,啟動(dòng)速度特別迅速,因此可以在不間斷服務(wù)的情況下,對軟件版本或者配置進(jìn)行升級,即使運行數月也無(wú)需重新啟動(dòng),幾乎可以做到7×24小時(shí)不間斷地運行。
同時(shí)使用Nginx和Apache
由于Nginx和Apache各自的優(yōu)勢,現在很多人選擇了讓兩者在服務(wù)器中共存。在服務(wù)器端讓Nginx在前,Apache在后。由Nginx做負載均衡和反向代理,并且處理靜態(tài)文件,講動(dòng)態(tài)請求(如PHP應用)交給Apache去處理
聯(lián)系客服