介紹 |
Apache HTTP 服務器被設計爲一個功能強大,而且靈活的 web 服務器,能夠在不少平臺與環境中工做。不一樣平臺和不一樣的環境每每須要不一樣的特性,或可能以不一樣的方式實現相同的特性最有效率。Apache httpd經過模塊化的設計來適應各類環境。這種設計容許網站管理員經過在編譯時或運行時,選擇哪些模塊將會加載在服務器中,來選擇服務器特性。php
Apache HTTP 服務器 2.0 擴展此模塊化設計到最基本的 web 服務器功能,它提供了能夠選擇的多處理模塊(MPM),用來綁定到網絡端口上,接受請求,以及調度子進程處理請求。web
擴展到這一級別的服務器模塊化設計,帶來兩個重要的好處:apache
Apache httpd 能更優雅,更高效率的支持不一樣的平臺。尤爲是Apache httpd 的 Windows 版本如今更有效率了,由於mpm_winnt 能使用原生網絡特性取代在Apache httpd 1.3 中使用的 POSIX 層。它也能夠擴展到其它平臺來使用專用的 MPM。vim
Apache httpd 能更好的爲有特殊要求的站點定製。例如,要求更高伸縮性的站點能夠選擇使用線程的 MPM,即worker 或 event;須要可靠性或者與舊軟件兼容的站點可使用prefork。安全
在用戶看來,MPM 很像其它 Apache httpd 模塊。主要是區別是,在任什麼時候間,必須有一個,並且只有一個 MPM 加載到服務器中。bash
可用的MPM列表:服務器
beos | 專門針對BeOS優化過的多路處理模塊(MPM),此模塊是BeOS系統的默認MPM模塊 |
mpmt_os2 | 專門針對OS/2優化過的混合多進程、多線程、多路處理模塊(MPM),此模塊是OS/2系統的默認MPM模塊 |
mpm_netware | 專門爲Novell NetWare優化的、線程化的多路處理模塊(MPM),此模塊是NetWare系統的默認MPM模塊 |
mpm_winnt | 用戶Windows系統系列的MPM,此模塊也是Windows系統的默認MPM模塊 |
work | 線程型的MPM,實現了一個混合的多線程多處理MPM,容許一個子進程中包含多個線程,相對於Prefork,Worker是Apache2.0版本中新增長的支持多線程和多進程混合模型的MPM。因爲使用多進程,再有每一個進程派生出多線程來處理,因此能夠處理相對海量的請求,而系統資源的開銷要小於基於進程的服務器。這種類型的MPM工做方式將是Apache之後的發展趨勢 |
prefork | prefork是Unix/Linux平臺上默認的MPM,它採用的預派生子進程方式也是Apache 1.3中採用的模式。prefork自己是不使用線程的,爲了保持兼容性,因此Apache 2.0版本中還使用它,另外一方面,prefork用單獨的子進程來處理不一樣的請求,每一個進程之間是獨立的,這也使它成爲最穩定的MPM之一 |
event |
默認MPM |
下表列出了不一樣系統的默認 MPM。若是你不在編譯時選擇,那麼它就是你將要使用的 MPM。網絡
Netware | mpm_netware |
OS/2 | mpmt_os2 |
Unix/Linux | prefork,worker或event,取決於平臺特性 |
Windows | mpm_winnt |
構建MPM爲靜態模塊 |
在所有平臺中,MPM 均可以構建爲靜態模塊。在構建時選擇一種MPM,連接到服務器中。若是要改MPM,必須從新構建。多線程
爲了使用指定的MPM,請在執行configure
腳本時,使用參數--with-mpm=NAME
。NAME 是指定的MPM名稱。併發
編譯完成後,可使用./httpd -l
來肯定選擇的MPM。此命令會列出編譯到服務器程序中的全部模塊,包括 MPM
構建MPM爲動態模塊 |
在 Unix 或相似平臺中,MPM能夠構建爲動態模塊,與其它動態模塊同樣在運行時加載。構建 MPM 爲動態模塊容許經過修改LoadModule
指令內容來改變MPM,而不用從新構建服務器程序。
在執行configure
腳本時,使用--enable-mpms-shared
選項能夠啓用此特性。當給出的參數爲 all
時,全部此平臺支持的MPM模塊都會被安裝。還能夠在參數中給出模塊列表。
默認MPM,能夠自動選擇或者在執行configure
腳本時經過--with-mpm
選項來指定,而後出如今生成的服務器配置文件中。編輯LoadModule
指令內容能夠選擇不一樣的MPM。
prefork,worker,event三種模式的區別 |
Apache 2.X 支持插入式並行處理模塊,稱爲多路處理模塊(MPM)。在編譯apache時必須選擇也只能選擇一個MPM,對類UNIX系統,有幾個不一樣的MPM可供選擇,它們會影響到apache的速度和可伸縮性。
Prefork MPM : 這個多路處理模塊(MPM)實現了一個非線程型的、預派生的web服務器,它的工做方式相似於Apache 1.3。它適合於沒有線程安全庫,須要避免線程兼容性問題的系統。它是要求將每一個請求相互獨立的狀況下最好的MPM,這樣若一個請求出現問題就不會影響到其餘請求。
這個MPM具備很強的自我調節能力,只須要不多的配置指令調整。最重要的是將MaxClients設置爲一個足夠大的數值以處理潛在的請求高峯,同時又不能太大,以至須要使用的內存超出物理內存的大小。
Worker MPM : 此多路處理模塊(MPM)使網絡服務器支持混合的多線程多進程。因爲使用線程來處理請求,因此能夠處理海量請求,而系統資源的開銷小於基於進程的MPM。可是,它也使用了多進程,每一個進程又有多個線程,以得到基於進程的MPM的穩定性。
每一個進程能夠擁有的線程數量是固定的。服務器會根據負載狀況增長或減小進程數量。一個單獨的控制進程(父進程)負責子進程的創建。每一個子進程能夠創建ThreadsPerChild數量的服務線程和一個監聽線程,該監聽線程監聽接入請求並將其傳遞給服務線程處理和應答。
不論是Worker模式或是Prefork 模式,Apache老是試圖保持一些備用的(spare)或者是空閒的子進程(空閒的服務線程池)用於迎接即將到來的請求。這樣客戶端就不須要在獲得服務前等候子進程的產生。
Event MPM:以上兩種穩定的MPM方式在很是繁忙的服務器應用下都有些不足。儘管HTTP的Keepalive方式能減小TCP鏈接數量和網絡負載,可是 Keepalive須要和服務進程或者線程綁定,這就致使一個繁忙的服務器會耗光全部的線程。 Event MPM是解決這個問題的一種新模型,它把服務進程從鏈接中分離出來。在服務器處理速度很快,同時具備很是高的點擊率時,可用的線程數量就是關鍵的資源限 制,此時Event MPM方式是最有效的。一個以Worker MPM方式工做的繁忙服務器可以承受每秒好幾萬次的訪問量(例如在大型新聞服務站點的高峯時),而Event MPM能夠用來處理更高負載。值得注意的是,Event MPM不能在安全HTTP(HTTPS)訪問下工做。
查看並配置Apache使用的MPM |
[root@GMQ ~]
# httpd -l #→列出支持使用的非DSO模塊
Compiled
in
modules:
core.c
prefork.c
http_core.c
mod_so.c
[root@GMQ ~]
# httpd -M #→列出已經裝載的全部模塊(包含靜態編譯和動態加載的模塊)
Loaded Modules:
core_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
auth_basic_module (shared)
auth_digest_module (shared)
authn_file_module (shared)
authn_alias_module (shared)
authn_anon_module (shared)
authn_dbm_module (shared)
[root@GMQ ~]
# vim /etc/sysconfig/httpd
#HTTPD=/usr/sbin/httpd.worker
HTTPD=
/usr/sbin/httpd
.worker
#設置Apache使用的MPM
MPM參數分析與設置 |
[root@GMQ ~]
# cat /etc/httpd/conf/httpd.conf #→查看prefork在apache裏的默認配置
<IfModule prefork.c>
StartServers 8
#→默認啓動的工做進程數;
MinSpareServers 5
#→最少空閒工做進程數,保存備用
MaxSpareServers 20
#→最大空閒工做進程數,保存備
ServerLimit 256
#→最大活動工做進程數;
MaxClients 256
#→併發請求的最大數;
MaxRequestsPerChild 4000
#→每一個子進程在生命週期內所可以服務的最多請求個數
<
/IfModule
>
apache的prefork MPM 是應用最廣的一個, 目前爲止我使用的服務器都採用prefork, 由於它夠穩定,並且我寫的LNMP/LNMPA一鍵安裝包也採用prefork爲apache的默認MPM模式。
prefork採用的是預派生子進程方式,用子進程處理不一樣的請求, 每一個請求對應一個子進程,進程之間是彼此獨立的。當apache啓動後會先啓動StartServers個子進程,等待1秒後會再建立兩個,再等待1秒後建立4個,再一秒後建立8個這樣直到建立滿MinSpareServers個子進程爲止,那麼此時MinSpareServers個子進程會待命,這種待命模式沒必要在新請求到來時從新建立, 必定程度上加快了進程的響應速度。
MaxSpareServers的值表明最大的待命進程數,若是待命進程數大於這個apache會自動kill掉多餘沒有啓用的進程。若是站點負載交大, 內存足夠多, 那麼能夠考慮加大MinSpareServers 和MaxSpareServers。有人問我那麼apache一個子進程到底佔用多大內存呢?其實這個跟apache加載的php模塊有關, 還跟php處理的腳本有關,通常來講一個子進程大概佔用2-10M左右。
MaxRequestWorkers (在以前的版本中稱之爲MaxClients),此參數很重要, 其表示apache能夠同時處理請求數,默認值是250, 咱們通常都會將其加大不少, 可是不能大於250豈不是很坑爹? 別擔憂, apache同時提供了另外一個指令ServerLimit,將這個指令和MaxRequestWorkers 設置相同便可,該指令用於修改apache默認256的限制,ServerLimit 的最大硬限制爲200000, 也就是說理論上咱們可讓apache同時處理20萬的請求, 至於這20萬請求過來以後apache是如何分配的就要看你的其餘參數的設置了。
MaxRequestsPerChild上面說到都是進程, 那麼這個MaxRequestsPerChild就表明的是每個進程所可以承受的最大請求數量, 若是某一個進程超過了這個數量則進程自動釋放全部內存而後自殺掉。此值能夠設置爲0, 0就是說永遠不結束, 這樣作的弊端是進程佔用內存過大並且容易內存溢出。不過對於KeepAlive連接, 只有第一個請求會被算進去, KeepAlive有效期類的其餘請求將不做數。
2)Apache Worker模式:
[root@GMQ ~]
# cat /etc/httpd/conf/httpd.conf#→查看worker在apache裏的默認配置
<IfModule worker.c>
StartServers 4
#→啓動的子進程的個數;
MaxClients 300
#→併發請求的最大數,保存備用;
MinSpareThreads 25
#→最小空閒線程數;保存備用;
MaxSpareThreads 75
#→最大空閒線程數;
ThreadsPerChild 25
#→每一個子進程可生成的線程數;
MaxRequestsPerChild 0
#→每一個子進程在生命週期內所可以服務的最多請求個數,0表示不限定;
<
/IfModule
>
worker的工做原理是,由主控制進程生成「StartServers」個子進程,每一個子進程中包含固定的ThreadsPerChild線程數,各個線程獨立地處理請求。一樣,爲了避免在請求到來時再生成線程,MinSpareThreads和MaxSpareThreads設置了最少和最多的空閒線程數;而"MaxClients"設置了全部子進程中的線程總數。若是現有子進程中的線程總數不能知足負載,控制進程將派生新的子進程。
"MinSpareThreads"和"MaxSpareThreads"的最大缺省值分別是75和250。這兩個參數對Apache的性能影響並不大,能夠按照實際狀況相應調節。
"ThreadsPerChild"是workerMPM中與性能相關最密切的指令。這個指令設置了每一個進程創建的進程數。子進程在啓動時創建這些線程後就不在創建新的線程了。每一個進程所擁有的全部線程的總數足夠大,以即可以處理可能的請求高峯。
worker模式下所能同時處理的請求總數是由子進程總數乘以"ThreadsPerChild"值決定的,應該大於"MaxClients"。若是顯式聲明瞭"ServerLimit",那麼它乘以ThreadsPerChild的值必須大於等於"MaxClients",並且"MaxClients"必須是"ThreadsPerChild"的整數倍,不然Apache將會自動調節到一個相應值(多是個非指望值).
3)Apache Event模式: