Apache 工作的三種模式:Prefork、Worker、Event

mimvp發表於2019-01-19

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.4 (Current)

Version 2.2 (Historical)

Version 2.0 (Historical)

Version 1.3 (Historical)

參考:https://httpd.apache.org/docs/

關於 Apache 配置優化,請參見米撲部落格:Apache 伺服器負載低訪問慢的原因分析和優化方案

相關文章