Apache下三種MPM模式:prefork,worker和event

Apache下三種MPM模式:prefork,worker和event


MPM(Multi-Processing Module,多進程處理模塊):
prefork,worker和event

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

 /usr/local/apache2/bin/httpd  -V
Server version: Apache/2.2.29 (Unix)
Server built:   Aug 20 2015 20:11:21
Server's Module Magic Number: 20051115:36
Server loaded:  APR 1.5.1, APR-Util 1.5.3
Compiled using: APR 1.5.1, APR-Util 1.5.3
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)

 

編譯的時候,通過configure的參數來指定
--with-mpm=prefork|worker|event

 cat /usr/local/apache2/build/config.nice"./configure" \
..."--with-apr=/usr/local/apr" \"--with-apr-util=/usr/local/apr-util" \"--with-z=/usr/local" \"--with-mpm=prefork" \
....

 

可以編譯爲三種都支持,通過修改配置來更換
--enable-mpms-shared=all

modules目錄下,會自動編譯出三個MPM的so文件,
在httpd.conf中,修改加載的模塊來改變MPM的模式:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

prefork 

"It's probably not advisable to use prefork unless you need a module that's not thread safe."
prefork模式,很古老,非常穩定的模式,不建議使用的模式,除非是在使用一個非線程安全的模塊。

爲了減少頻繁創建和銷燬進程的開銷,Apache在啓動之初,預先fork一些子進程,然後等待請求進來。

每個子進程只有一個線程,在一個時間點內,只能處理一個請求。

優點:成熟穩定,兼容所有新老模塊。
MOD_PHP拓展不需要支持線程安全,不需要擔心線程安全的問題。

缺點:一個進程相對佔用更多的系統資源,消耗更多的內存。
不擅長處理高併發請求,高併發場景下會將請求放進隊列中,
一直等到有可用進程,請求才會被處理。

使用場景:
儘量不推薦在此模式下裕興,除非模塊無法在線程模式下運行。
PHP在非線程安全模下,推薦使用FastCGI和php-fpm模式。


worker 

線程模式,內存佔用會少一些,在高併發方面表現的會更好。

啓動時會fork幾個子進程,每個子進程創建一些線程,同時包括一個監聽線程。

每個請求過來,會被分配到1個線程來服務。
線程比起進程會更輕量,線程通常會共享父進程的內存空間。
在高併發的場景下,比prefork有更多的可用線程,性能表現會更優秀一些。

如果一個線程異常掛了,會導致父進程連同其他正常的子線程都掛了。
爲了防止這場異常場景出現,就需要使用多個進程再加多線程,如果某個線程出現異常,受影響的只是Apache的一部分服務,而不是整個服務。

優點:佔據更少的內存,高併發下表現更優秀。

缺點:必須考慮線程安全的問題,因爲多個子線程是共享父進程的內存地址的。
keep-alive的長連接方式,是爲了讓下一次的socket通信複用之前創建的連接,從而,減少連接的創建和銷燬的系統開銷。保持連接,會讓某個進程或者線程一直處於等待狀態,即使沒有數據過來。如果使用keep-alive的長連接方式,某個線程會一直被佔據,需要一直等待到超時纔會被釋放。

使用場景:
使用Apache httpd 2.2或2.4版本,同時打算運行SSL服務。
除非兼容性問題解決不了,一般比較推薦worker模式。

event


"it's just been moved from 'experimental' to 'stable' status in Apache 2.4."
event MPM,需要Linux系統(Linux 2.6+)對EPoll的支持,同時建議在httpd 2.4.x版本下使用。
event 和worker模式很像,解決了keep-alive場景下,長期被佔用的線程的資源浪費問題。
event MPM中,會有一個專門的線程來管理keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又允許它釋放,增強了高併發場景下的請求處理能力。
event MPM在遇到某些不兼容的模塊時會失效,將會回退到worker模式,一個工作線程處理一個請求。


使用場景:
使用apache httpd 2.4,同時使用到多線程,event是最佳的運行模式。

httpd 2.2.x文檔下:

Warning
This MPM is experimental, so it may or may not work as expected.

This MPM does not perform well on older platforms which lack good threading, but the requirement for EPoll or KQueue makes this moot.

To use this MPM on FreeBSD, FreeBSD 5.3 or higher is recommended. However, it is possible to run this MPM on FreeBSD 5.2.1, if you use libkse (see man libmap.conf).
For NetBSD, at least version 2.0 is recommended.
For Linux, a 2.6 kernel is recommended. It is also necessary to ensure that your version of glibc has been compiled with support for EPoll.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章