Apache 的三種工作模式(Prefork、Worker、Event)
Web服務器Apache目前一共有三種穩定的MPM(Multi-Processing Module,多進程處理模塊)模式。
它們分別是prefork,worker、event,它們同時也代表這Apache的演變和發展。
本文原文轉自米撲博客:Apache 工作的三種模式:Prefork、Worker、Event
如何查看我們的Apache的工作模式呢?可以使用httpd -V 命令查看,如我安裝的Apache 2.4版本。
# httpd -V Server version: Apache/2.4.34 (Unix) Server built: Aug 2 2018 19:44:29 Server's Module Magic Number: 20120211:79 Server loaded: APR 1.6.3, APR-UTIL 1.6.1 Compiled using: APR 1.6.3, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count)
或者,更直接的命令 httpd -l 或 apachectl -V | grep -i mpm
# httpd -l Compiled in modules: core.c mod_so.c http_core.c event.c # apachectl -V | grep -i mpm Server MPM: event
這里使用的是event模式,在apache的早期版本2.0默認prefork,2.2版本是worker,2.4版本是event,詳見米撲博客:Apache 服務器負載低訪問慢的原因分析和優化方案
在configure配置編譯參數的時候,可以使用--with-mpm=prefork|worker|event
來指定編譯為那一種MPM,當然也可以用編譯為三種都支持:--enable-mpms-shared=all
,這樣在編譯的時候會在modules目錄下自動編譯出三個MPM文件的so,然后通過修改httpd.conf配置文件更改MPM
1、Prefork MPM
Prefork MPM實現了一個非線程的、預派生的web服務器。它在Apache啟動之初,就先預派生一些子進程,然后等待連接;可以減少頻繁創建和銷毀進程的開銷,每個子進程只有一個線程,在一個時間點內,只能處理一個請求。這是一個成熟穩定,可以兼容新老模塊,也不需要擔心線程安全問題,但是一個進程相對占用資源,消耗大量內存,不擅長處理高並發的場景。
如何配置在Apache的配置文件httpd.conf的配置方式:
<IfModule mpm_prefork_module> StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 250 MaxConnectionsPerChild 1000 </IfModule>
StartServers
服務器啟動時建立的子進程數量,prefork默認是5,
MinSpareServers
空閑子進程的最小數量,默認5;如果當前空閑子進程數少於MinSpareServers
,那么Apache將以最大每秒一個的速度產生新的子進程。此參數不要設的太大。
MaxSpareServers
空閑子進程的最大數量,默認10;如果當前有超過MaxSpareServers
數量的空閑子進程,那么父進程會殺死多余的子進程。次參數也不需要設置太大,如果你將其設置比MinSpareServers
小,Apache會自動將其修改為MinSpareServers +1
的數量。
MaxRequestWorkers
限定服務器同一時間內客戶端最大接入的請求數量,默認是256;任何超過了MaxRequestWorkers
限制的請求都要進入等待隊列,一旦一個個連接被釋放,隊列中的請求才將得到服務,如果要增大這個數值,必須先增大ServerLimit
。在Apache2.3.1版本之前這參數MaxRequestWorkers
被稱為MaxClients
。
MaxConnectionsPerChild
每個子進程在其生命周期內允許最大的請求數量,如果請求總數已經達到這個數值,子進程將會結束,如果設置為0,子進程將永遠不會結束。在Apache2.3.9之前稱之為MaxRequestsPerChild
。
這里建議設置為非零,注意原因:
1)能夠防止(偶然的)內存泄漏無限進行,從而耗盡內存。
2)給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量(重生的機會)。
2、Worker MPM
和prefork模式相比,worker使用了多進程和多線程的混合模式,worker模式也同樣會先預派生一些子進程,然后每個子進程創建一些線程,同時包括一個監聽線程,每個請求過來會被分配到一個線程來服務。線程比起進程會更輕量,因為線程是通過共享父進程的內存空間,因此,內存的占用會減少一些,在高並發的場景下會比prefork有更多可用的線程,表現會更優秀一些;另外,如果一個線程出現了問題也會導致同一進程下的線程出現問題,如果是多個線程出現問題,也只是影響Apache的一部分,而不是全部。由於用到多進程多線程,需要考慮到線程的安全了,在使用keep-alive長連接的時候,某個線程會一直被占用,即使中間沒有請求,需要等待到超時才會被釋放(該問題在prefork模式下也存在)。
如何配置在Apache的配置文件httpd.conf的配置方式:
<IfModule mpm_worker_module> StartServers 3 ServerLimit 16 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 1000 </IfModule>
配置參數解釋:
StartServers
服務器啟動時建立的子進程數量,在workers模式下默認是3.
ServerLimit
系統配置的最大進程數量,默認不顯示,自己添加上
MinSpareThreads
空閑子進程的最小數量,默認75
MaxSpareThreads
空閑子進程的最大數量,默認250
ThreadsPerChild
每個子進程產生的線程數量,默認是64
MaxRequestWorkers / MaxClients
限定服務器同一時間內客戶端最大接入的請求數量.
MaxConnectionsPerChild
每個子進程在其生命周期內允許最大的請求數量,如果請求總數已經達到這個數值,子進程將會結束,如果設置為0,子進程將永遠不會結束。在Apache2.3.9之前稱之為MaxRequestsPerChild
。
這里建議設置為非零,注意原因:
1)能夠防止(偶然的)內存泄漏無限進行,從而耗盡內存;
2)給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量(重生的機會)。
Worker模式下所能同時處理的請求總數是由子進程總數乘以ThreadsPerChild
值決定的,應該大於等於MaxRequestWorkers
。
如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。默認ServerLimit
最大的子進程總數是16,加大時也需要顯式聲明ServerLimit
(最大值是20000)。
需要注意的是,如果顯式聲明了ServerLimit
,那么它乘以 MaxRequestWorkers
必須是hreadsPerChild
的整數倍,否則 Apache將會自動調節到一個相應值。
3、Event MPM
這是Apache最新的工作模式,它和worker模式很像,不同的是在於它解決了keep-alive長連接的時候占用線程資源被浪費的問題,在event工作模式中,會有一些專門的線程用來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務器的線程,執行完畢后,又允許它釋放。這增強了在高並發場景下的請求處理。
如何配置在Apache的配置文件httpd.conf的配置方式:
<IfModule mpm_event_module> StartServers 3 ServerLimit 16 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 1000 </IfModule>
event 模式與 worker 模式完全一樣,參考 worker 模式參數即可,這里不再重復。
Apache httpd 能更好的為有特殊要求的站點定制。
例如,要求更高伸縮性的站點可以選擇使用線程的 MPM,即 worker 或 event; 需要可靠性或者與舊軟件兼容的站點可以使用 prefork。
常見問題
查看apache的error日志,可以發現許多系統運行中的問題。
server reached MaxRequestWorkers setting
[mpm_prefork:error] [pid 1134] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
進程或者線程數目達到了MaxRequestWorkers,可以考慮增加這個值,當然先考慮增加硬件,如內存大小、CPU、SSD硬盤等。
scoreboard is full
[mpm_event:error] [pid 7555:tid 140058436118400] AH00485: scoreboard is full, not at MaxRequestWorkers
這個問題好像是apache2自帶的bug,我們無力解決。好在這個問題一般只會影響單個線程,所以暫時可以忍。
StackOverflow: Scoreboard is full,not at MaxRequestWorkers
1、I had this same problem. I tried different Apache versions and MPMs. I seem to get this alot with MPM Worker. Also error does not reoccur using Apache 2.2.2,Are you using cPanel? IF so try /upcp --force and increase StartServers to a higher amount like 50 as that's all I did to get this error away.
2、Try EnableMMAP Off in 00_default_settings.conf
apache 主要版本有:
-
Version 2.2 (Historical)
-
Version 2.0 (Historical)
-
Version 1.3 (Historical)
參考:https://httpd.apache.org/docs/
關於 Apache 配置優化,請參見米撲博客:Apache 服務器負載低訪問慢的原因分析和優化方案
參考推薦:
Apache 工作的三種模式:Prefork、Worker、Event
Apache 實現https+Apache http訪問轉到https