轉載自:https://blog.csdn.net/ccscu/article/details/70182476
https://blog.csdn.net/MrCoders/article/details/54911202
截止到目前最新的Apache2.4.25,Apache總共支持三種MPM(多進程處理模塊)模式,分別是Prefork、worker及event。這三種模式代表了Apache的演變和發展。
Apache2.2中,默認啓用prefork模式,同時引進了實驗性質的event模式;
Apache2.4中,正式支持並且默認使用了event模式。並且可以在編譯的時候增加了選項enable-mpms-shared來編譯MPM並在編譯後可以動態加載。
可以通過apachectl -V查看當前Apache的工作模式,比如在Apache2.2.31上查看:
- Server version: Apache/2.2.31 (Unix)
- Server built: Dec 25 2016 07:02:07
- Server's Module Magic Number: 20051115:40
- Server loaded: APR 1.5.2, APR-Util 1.5.4
- Compiled using: APR 1.5.2, APR-Util 1.5.4
- Architecture: 64-bit
- Server MPM: Prefork
- threaded: no
- forked: yes (variable process count)
- $ /usr/local/apache24/bin/httpd -V
- Server version: Apache/2.4.18 (Unix)
- Server built: Feb 18 2016 02:28:26
- Server's Module Magic Number: 20120211:52
- Server loaded: APR 1.5.2, APR-UTIL 1.5.4
- Compiled using: APR 1.5.2, APR-UTIL 1.5.4
- Architecture: 64-bit
- Server MPM: event
- threaded: yes (fixed thread count)
- forked: yes (variable process count)
一、Prefork MPM
Prefork MPM實現了一個非線程、預派生的工作模式。它在Apache啓動之初,就會預派生一些子進程,然後等待連接。可以減少頻繁創建和銷燬進程的開銷,每個子進程只有一個線程。它成熟穩定,可以兼容新老模塊,也不需要擔心線程安全問題。但是一個進程相對地佔用更多的資源,消耗大量內存,不擅長處理高併發的場景。
- <IfModule mpm_prefork_module>
- StartServers 5
- MinSpareServers 5
- MaxSpareServers 10
- MaxClients 150
- MaxRequestsPerChild 0
- </IfModule>
這個值的計算公式可以參考:
apache_max_process_with_good_perfermance < (total_hardware_memory / apache_memory_per_process ) * 2 ;
apache_max_process = apache_max_process_with_good_perfermance * 1.5 ;
其中httpd平均佔用內存:
ps aux|grep -v grep|awk '/httpd/{sum+=$6;n++};END{print sum/n}'
MaxRequestsPerChild這個值的含義是處理多少個請求後該進程自動銷燬,默認值0意味着永不銷燬。當負載較高時,爲了使每個進程處理更多的請求,避免銷燬、創建進程的開銷,一般建議設置爲0或較大的數字。但是也要注意可能會造成進程佔用的內存不能得到釋放,所以這個值不能設置得太大,也不能太小,大了會影響資源的釋放,小了會導致Apache不斷地fork進程。
建議值:1分鐘pv(訪問量)/MaxClients
二、worker MPM
與Prefork工作模式相比,worker使用了多進程和多線程的混合模式,worker模式也同樣會預派生一些子進程,然後每個子進程創建一些線程,同時包括一個監聽線程,每個請求過來會被分配到一個線程來服務。線程比進程更加輕量級,因爲線程通常會共享父進程的內存地址的,因此內存佔用會減少一些。
同時如果一個線程異常掛了,會導致父進程和它的其他正常子線程都掛了,這樣也只會影響Apache的一部分,而不是整個服務。
缺點使必須考慮線程安全性,因爲多個子進程是共享父進程的內存地址的。如果使用keep-alive的長連接方式,某個線程會被一直佔據,也許中間沒有任何請求,需要等到超時纔會被釋放。如果過多的線程被這樣佔據,也會導致在高併發下的無服務線程可用。
三、event MPM
和worker工作模式很像,最大的區別是解決了在keep-alive場景下,長期被佔用的線程的資源浪費問題,在event MPM中,會有一個專門的線程來管理這些keep-alive線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又允許它釋放,這樣增強了在高併發場景下的請求處理能力。
就使用PHP而言,fastCGI和php-fpm是更推薦的使用模式。
現在的最新瀏覽器,在單個域名下的連接數變得越來越多(通常都是使用keep-alive),主流瀏覽器是2-6個(還有繼續增長趨勢,爲了加快頁面的併發下載速度)。高併發場景,會越來越成爲Web系統的一種常態。Apache很成熟,同時也揹負了比較重的歷史代碼和模塊,因此,在Web系統比較方面,Nginx在不少場景下,表現比起Apache更爲出色。