本博文主要參數 Apache 2.2文檔以及Apache模塊開發指南html
Apache的整個運行能夠分爲兩個階段:啓動階段和運行階段。web
在啓動階段時,它以ROOT特權來啓動,進行解析配置文件(通常就是httpd.conf)、加載模塊和初始化一些日誌文件及內存共享段等操做,在啓動階段準備結束時,apache的控制轉向多處理模塊MPM,此時使得MPM可以在系統特權級運行,從而管理接下來的運行階段。由於當處於運行階段時,程序會放棄ROOT特權,以接收並處理網絡中用戶的服務請求,因此MPM也是在啓動階段初始化。apache
一,什麼是MPM安全
MPM,是Multi -Processing Modules的縮寫,就是多處理模塊的意思,它是在Apache 2.0中引入的一個概念,共引入目標是將Apache的結構可以模塊化,把核心的任務處理做爲一個可插拔的模塊來運行,這樣就很容易根據不一樣的環境和應用來更有效的優化Apache的運行,它是Apache2.X中最影響其性能的,最核心的特性,由於直接決定了Apache的工做方式。這裏有一個問題是:它究竟怎麼樣影響了Apache。服務器
能夠這麼說:它決定了Apache以什麼樣的方式接入外部請求,如何Apache內部怎麼樣處理這個請求過程,這固然是最核心的了吧,好比它能夠決定在處理外部請求的時候,需不須要啓動多線程,若是是用多線程,最多能夠多少個線程,一個進程能夠產生最多多少個線程,相似於這種配置,都來自於MPM。MPM有一些指令能夠專門用於調節父進程如何產生子進程,主要是StartServers,MinSpareServers,MaxSpareServers,MaxClients等,下面會介紹這些指令是什麼意思。網絡
它提供Apache服務程序和其所在的操做系統之間的接口,這個模塊的主要職責是:多線程
- 根據Apache運行的操做系統平臺來優化Apache。
- 提升Apache的效率。
- 保證Apache的安全。
其實MPM自己也是一個模塊,它是Apache中惟一一個系統層的模塊,Apache在編譯的時候選定一個所要使用的MPM模塊,咱們先來了解一下MPM模塊在系統結構中的位置併發
在任什麼時候候,一個正常的Apache都只有一個MPM模塊在運行。ide
二,有哪些MPM能夠被使用模塊化
在安裝apache時,咱們能夠查看哪些MPM模塊能夠被使用。
- [root@localhost httpd-2.2.11]# ./configure --help | grep mpm
- --with-mpm=MPM Choose the process model for Apache to use.
- MPM={beos|event|worker|prefork|mpmt_os2}
- beos是BEOS上的缺省MPM模塊。
- mpmt_os2,這是專門針對OS/2優化過的混合多進程多線程多路處理模塊(MPM)。
- event,一個標準workerMPM的實驗性變種。
- worker,線程型的MPM,實現了一個混合的多線程多處理MPM,容許一個子進程中包含多個線程。
- prefork,一個非線程型的、預派生的MPM。
下面分針對這些模塊進行討論,咱們怎麼知道當前apache是編譯了哪一個MPM使用呢?
- [root@localhost httpd-2.2.11]# /install/apache2/bin/httpd -l
- Compiled in modules:
- core.c
- prefork.c
- http_core.c
- mod_so.c
- [root@localhost httpd-2.2.11]#
這表示Apache當前的正在工做的MPM是prefork工做方式的MPM,這也是一種缺省的模塊,若是須要其它的MPM模塊,在編譯的時候用--with-mpm指定。
三,prefork
Apache MPM prefork實現了一
個非線程型的、預派生的web服務器。適合於沒有線程安全庫,須要避免線程兼容性問題的系統。它是
要求將每一個請求相互獨立的狀況下最好的MPM,這樣若一個請求出現問題就不會影響到其餘請求。這個MPM具備很強的自我調節能力,只須要不多的配置指令調整。最重要的是將MaxClients設置爲一個足夠大的數值以處理潛在的請求高峯,同時又不能太大,以至須要使用的內存超出物理內存的大小。
這種MPM的工做方式是:由一個單獨的控制進程(父進程)產生子進程,而後將這些子進程用於監聽請求並做出應答,這些子進程在處理時並不產生線程。另外,Apache老是試圖保持一些備用的(spare)或者是空閒的子進程用於迎接即將到來的請求。這樣客戶端就不須要在獲得服務前等候子進程的產生。
能夠用於配置該MPM如何工做的主要參數有:
- StartServers。
StartServers指令設置了服務器啓動時創建的子進程數量。由於子進程數量動態的取決於負載的輕重,全部通常沒有必要調整這個參數。不一樣的MPM默認值也不同。對於worker默認值是"3"。對於prefork默認值是"5"。
- MinSpareServers。
MinSpareServers指令設置空閒子進程的最小數量。所謂空閒子進程是指沒有正在處理請求的子進程。若是當前空閒子進程數少於MinSpareServers ,那麼Apache將以最大每秒一個的速度產生新的子進程。只有在很是繁忙機器上才須要調整這個參數。將此參數設的太大一般是一個壞主意。。
- MaxSpareServers。MaxSpareServers指令設置空閒子進程的最大數量。所謂空閒子進程是指沒有正在處理請求的子進程。若是當前有超過MaxSpareServers數量的空閒子進程,那麼父進程將殺死多餘的子進程。只有在很是繁忙機器上才須要調整這個參數。將此參數設的太大一般是一個壞主意。若是你將該指令的值設置爲比MinSpareServers小,Apache將會自動將其修改爲"MinSpareServers+1"。
- MaxClients。MaxClients指令設置了容許同時伺服的最大接入請求數量。任何超過MaxClients限制的請求都將進入等候隊列,直到達到ListenBacklog指令限制的最大值爲止。一旦一個連接被釋放,隊列中的請求將獲得服務。對於非線程型的MPM(也就是prefork),MaxClients表示能夠用於伺服客戶端請求的最大子進程數量,默認值是256。要增大這個值,你必須同時增大ServerLimit 。對於線程型或者混合型的MPM(也就是beos或worker),MaxClients表示能夠用於伺服客戶端請求的最大線程數量。線程型的beos的默認值是50。對於混合型的MPM默認值是16(ServerLimit)乘以25(ThreadsPerChild)的結果。所以要將MaxClients增長到超過16個進程才能提供的時候,你必須同時增長ServerLimit的值。。
- MaxRequestsPerChild。每一個子進程在其生存期內容許伺服的最大請求數量,默認爲10000.到達MaxRequestsPerChild的限制後,子進程將會結束。若是 MaxRequestsPerChild爲」0″,子進程將永遠不會結束。將MaxRequestsPerChild設置成非零值有兩個好處:
1.能夠防止(偶然的)內存泄漏無限進行,從而耗盡內存。
2.給進程一個有限壽命,從而有助於當服務器負載減輕的時候減小活動進程的數量。
- ServerLimit。對於prefork MPM,這個指令設置了MaxClients最大容許配置的數值。對於workerMPM,這個指令和ThreadLimit結合使用設置了MaxClients最大容許配置的數值。任何在重啓期間對這個指令的改變都將被忽略,但對MaxClients的修改卻會生效。
配置舉例:
- <IfModule prefork.c>
- StartServers 4 Apache啓動時開啓的子進程個數
- MinSpareServers 4 最小的空閒子進程
- MaxSpareServers 6 最大的空閒子進程
- ServerLimit 15
- MaxClients 12 以避免產生大量的進程佔用內存,影響系統性能
- MaxRequestsPerChild 1200 子進程在處理了1200個請求以後,就會被銷燬,而後建立新進程。
- </IfModule>
四,worker
此多路處理模塊(MPM)使網絡服務器支持混合的多線程多進程。因爲使用線程來處理請求,因此能夠處理海量請求,而系統資源的開銷小於基於進程的MPM。可是,它也使用了多進程,每一個進程又有多個線程,以得到基於進程的MPM的穩定性。控制這個MPM的最重要的指令是,控制每一個子進程容許創建的線程數的ThreadsPerChild指令,和控制容許創建的總線程數的MaxClients指令。
每一個進程能夠擁有的線程數量是固定的。服務器會根據負載狀況增長或減小進程數量。一個單獨的控制進程(父進程)負責子進程的創建。每一個子進程能夠創建ThreadsPerChild數量的服務線程和一個監聽線程,該監聽線程監聽接入請求並將其傳遞給服務線程處理和應答。
Apache老是試圖維持一個備用(spare)或是空閒的服務線程池。這樣,客戶端無須等待新線程或新進程的創建便可獲得處理。初始化時創建的進程數量由StartServers指令決定。隨後父進程檢測全部子進程中空閒線程的總數,並新建或結束子進程使空閒線程的總數維持在MinSpareThreads和MaxSpareThreads所指定的範圍內。因爲這個過程是自動調整的,幾乎沒有必要修改這些指令的缺省值。能夠並行處理的客戶端的最大數量取決於MaxClients指令。活動子進程的最大數量取決於MaxClients除以ThreadsPerChild的值。
有兩個指令設置了活動子進程數量和每一個子進程中線程數量的硬限制。要想改變這個硬限制必須徹底中止服務器而後再啓動服務器(直接重啓是不行的),ServerLimit是活動子進程數量的硬限制,它必須大於或等於MaxClients除以ThreadsPerChild的值。ThreadLimit是全部服務線程總數的硬限制,它必須大於或等於ThreadsPerChild指令。這兩個指令必須出如今其餘workerMPM指令的前面。
在設置的活動子進程數量以外,還可能有額外的子進程處於"正在停止"的狀態可是其中至少有一個服務線程仍然在處理客戶端請求,直到到達MaxClients以至結束進程,雖然實際數量會很小。這個行爲可以經過如下禁止特別的子進程停止的方法來避免:
- 將MaxRequestsPerChild設爲"0"。
- 將MaxSpareThreads和MaxClients設爲相同的值。
一個典型的該類型MPM配置以下:
- ServerLimit 16
- StartServers 2
- MaxClients 150
- MinSpareThreads 25
- MaxSpareThreads 75
- ThreadsPerChild 25
五,小結
Prefork MPM基於非線程模型,由獨立的進程建立多個子進程的方式來工做,它在全部狀況下都很安全,對運行非線程安全(non-thread-safe)模式的軟件如PHP,它是惟一的安全選擇。另外,對於某些應用程序,包括在 Apache 1.3上很是流行的程序(如簡單靜態頁面、CGI腳本等),Prefork MPM是最好的選擇。另外一方面,prefork用單獨的子進程來處理不一樣的請求,進程之間是彼此獨立的,這也使其成爲最穩定的MPM之一。可是因爲每個請求都會產生一個新的進程,致使系統資源(尤爲是內存)消耗的很快,一旦併發量較大的時候,大量的Apache進程會佔用巨大的內存空間。
Worker MPM基於線程模式,具備內存消耗低(對繁忙的服務很重要)、擴展性在某些特定應用狀況下比Prefork更好等優勢。在這個模式下,採用的進程和線程混合的形式處理請求。因爲使用線程來處理,因此能夠處理相對海量的請求,而系統資源的開銷要小於基於進程的Prefork模式。
以上兩種穩定的MPM方式在很是繁忙的服務器應用下都有些不足。儘管HTTP的Keepalive方式能減小TCP鏈接數量和網絡負載,可是 Keepalive須要和服務進程或者線程綁定,這就致使一個繁忙的服務器會耗光全部的線程。