1. 程式人生 > >Apache學習---多程序處理模組(MPM)原理詳解

Apache學習---多程序處理模組(MPM)原理詳解

 

 

 

 

 

檢視Apache的模式,可以使用httpd -V命令來檢視:

1. prefork MPM

prefork模式可以算是很古老但是非常穩定的Apache模式。Apache在啟動之初,就預先fork一些子程序,然後等待請求進來。之所以這樣做,是為了減少頻繁建立和銷燬程序的開銷。每個子程序只有一個執行緒,在一個時間點內,只能處理一個請求。
優點:成熟穩定,相容所有新老模組。同時,不需要擔心執行緒安全的問題。(我們常用的mod_php,PHP的拓展不需要支援執行緒安全)
缺點:一個程序相對佔用更多的系統資源,消耗更多的記憶體。而且,它並不擅長處理高併發請求,在這種場景下,它會將請求放進佇列中,一直等到有可用程序,請求才會被處理。

Apache的httpd.conf中的配置方式:

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers         10
    MaxRequestWorkers      250
    MaxConnectionsPerChild   0
</IfModule>

  

2. worker MPM

worker模式比起上一個,是使用了多程序和多執行緒的混合模式。它也預先fork了幾個子程序(數量比較少),然後每個子程序建立一些執行緒,同時包括一個監聽執行緒。每個請求過來,會被分配到1個執行緒來服務。執行緒比起程序會更輕量,因為執行緒通常會共享父程序的記憶體空間,因此,記憶體的佔用會減少一些。在高併發的場景下,因為比起prefork有更多的可用執行緒,表現會更優秀一些。
有些人會覺得奇怪,那麼這裡為什麼不完全使用多執行緒呢,還要引入多程序?
原因主要是需要考慮穩定性,如果一個執行緒異常掛了,會導致父程序連同其他正常的子執行緒都掛了(它們都是同一個程序下的)。為了防止這場異常場景出現,就不能全部使用執行緒,使用多個程序再加多執行緒,如果某個執行緒出現異常,受影響的只是Apache的一部分服務,而不是整個服務。

優點:佔據更少的記憶體,高併發下表現更優秀。

缺點:必須考慮執行緒安全的問題,因為多個子執行緒是共享父程序的記憶體地址的。如果使用keep-alive的長連線方式,某個執行緒會一直被佔據,也許中間幾乎沒有請求,需要一直等待到超時才會被釋放。如果過多的執行緒,被這樣佔據,也會導致在高併發場景下的無服務執行緒可用。(該問題在prefork模式下,同樣會發生)

注:keep-alive的長連線方式,是為了讓下一次的socket通訊複用之前建立的連線,從而,減少連線的建立和銷燬的系統開銷。保持連線,會讓某個程序或者執行緒一直處於等待狀態,即使沒有資料過來。

Apache的httpd.conf中的配置方式:

<IfModule mpm_worker_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>

  

3. event MPM

這個是Apache中最新的模式,在現在版本里的已經是穩定可用的模式。它和worker模式很像,最大的區別在於,它解決了keep-alive場景下,長期被佔用的執行緒的資源浪費問題(某些執行緒因為被keep-alive,空掛在哪裡等待,中間幾乎沒有請求過來,甚至等到超時)。event MPM中,會有一個專門的執行緒來管理這些keep-alive型別的執行緒,當有真實請求過來的時候,將請求傳遞給服務執行緒,執行完畢後,又允許它釋放。這樣增強了高併發場景下的請求處理能力。

event MPM在遇到某些不相容的模組時,會失效,將會回退到worker模式,一個工作執行緒處理一個請求。官方自帶的模組,全部是支援event MPM的。

注意一點,event MPM需要Linux系統(Linux 2.6+)對EPoll的支援,才能啟用。

還有,需要補充的是HTTPS的連線(SSL),它的執行模式仍然是類似worker的方式,執行緒會被一直佔用,知道連線關閉。部分比較老的資料裡,說event MPM不支援SSL,那個說法是幾年前的說法,現在已經支援了

Apache的httpd.conf中的配置方式:

<IfModule mpm_event_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>