Apache三種工作模式介紹與配置
一、Apache的三種工作模式介紹及相關查看方法
1、Apache三種工作模式簡介
Apache目前一共有三種穩定的MPM(Multi-Processing Module,多進程處理模塊)模式。它們分別是prefork,worker和event,它們同時也代表這Apache的演變和發展。
Apache在configure配置編譯參數的時候,可以使用 --with-mpm=prefork|worker|event 來指定編譯為那一種MPM,當然也可以用編譯為三種都支持:--enable-mpms-shared=all,這樣在編譯的時候會在modules目錄下自動編譯出三個
2、Apache工作模式查看方法
在Linux中,我們yum安裝的Apache可以用httpd –l,編譯安裝的Apache可以使用Apache安裝路徑下面的bin/apachectl -l 查看安裝的模塊是prefork模式還是worker模式(默認是prefork模式)。
方法1:可查看Apache工作模式(這裏使用的是prefork模式)
[root@localhost ~]# /usr/local/apache2/bin/apachectl -l
Compiled in modules:
core.c
mod_so.c
http_core.c
prefork.c
方法2:可查看Apache版本信息及工作模式(這裏使用的是worker模式)
[root@localhost ~]# /usr/local/apache2/bin/apachectl -V
Server version: Apache/2.4.7 (Unix)
Server built: Apr 17 2018 11:12:53
Server's Module Magic Number: 20120211:27
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: worker
threaded: yes (fixed thread count)
forked: yes (variable process count)
3、查看Apache編譯安裝的參數
[root@localhost ~]# cat /usr/local/apache2/build/config.nice
#! /bin/sh
#
# Created by configure
"./configure" \
"--prefix=/usr/local/apache2" \
"--with-apr=/usr/local/apr" \
"--with-apr-util=/usr/local/apr-util" \
"--enable-deflate" \
"--enable-expires" \
"--enable-headers" \
"--enable-modules=most" \
"--enable-so" \
"--with-mpm=worker" \
"--enable-rewrite" \
"--enable-charset-lite" \
"--enable-cgid" \
"--enable-cgi" \
"$@"
二、Apache的prefork工作模式原理及相關介紹
1、Apache的prefork模式工作原理
prefork模式(默認模式)是很古老但是非常穩定的模式。使用的是多個子進程,Apache在啟動之初,控制進程會建立若幹個子進程,然後等待請求進來,並且總是視圖保持一些備用的子進程。為了不在請求到來時再生成子進程,所以要根據需求不斷的創建新的子進程,最大可以達到每秒32個直到滿足需求為止。之所以這樣做,是為了減少頻繁創建和銷毀進程的開銷。每個子進程中只有一個線程,在一個時間點內,只能處理一個請求。
在Unix系統中,父進程通常以root身份運行以便邦定80端口,而 Apache產生的子進程通常以一個低特權的用戶運行。User和Group指令用於配置子進程的低特權用戶。運行子進程的用戶必須要對他所服務的內容有讀取的權限,但是對服務內容之外的其他資源必須擁有盡可能少的權限。
2、Apache的prefork模式安裝方法
在編譯安裝Apache的過程中,加入參數--with-mpm=prefork即可,如果不加也可以,因為Apache默認會采用prefork模式進行編譯安裝。也可以使用--enable-mpms-shared=all,這樣在編譯的時候會在modules目錄下自動編譯出三個MPM文件的so,然後通過修改httpd.conf配置文件更改MPM即可。
3、Apache的prefork模式優缺點
優點:成熟,兼容所有新老模塊。進程之間完全獨立,使得它非常穩定。同時,不需要擔心線程安全的問題。(我們常用的mod_php,PHP的拓展不需要支持線程安全)
缺點:一個進程相對占用更多的系統資源,消耗更多的內存。而且,它並不擅長處理高並發請求,在這種場景下,它會將請求放進隊列中,一直等到有可用進程,請求才會被處理。
4、Apache的prefork模式配置參數說明
[root@localhost ~]# vim /usr/local/apache2/conf/extra/ httpd-mpm.conf
<IfModule mpm_prefork_module>
StartServers 5 服務啟動時初始的進程數,默認5
MinSpareServers 5 最小的空閑子進程數,默認5
MaxSpareServers 10 最大的空閑子進程數,默認10
MaxRequestWorkers 250
限定同一時間內客戶端最大接入的請求數量,默認是250
MaxConnectionsPerChild 0
每個子進程在其生命周期內允許最大的請求數量,如果請求總數已經達到這個數值,子進程將會結束,如果設置為0,子進程將永遠不會結束。將該值設置為非0值,可以防止運行PHP導致的內存泄露。
</IfModule>
三、Apache的worker模式工作原理及相關介紹
1、Apache的worker模式工作原理
worker模式和prefork模式相比,worker模式使用了多進程和多線程的混合模式,worker模式也同樣會先預派生一些子進程,然後每個子進程創建一些線程,同時包括一個監聽線程,每個請求過來會被分配到一個線程來服務。線程比起進程會更輕量,因為線程是通過共享父進程的內存空間,因此,內存的占用會減少一些,在高並發的場景下會比prefork有更多可用的線程,表現會更優秀一些。
另外,如果一個線程出現了問題也會導致同一進程下的線程出現問題,如果是多個線程出現問題,也只是影響Apache的一部分,而不是全部。由於用到多進程多線程,需要考慮到線程的安全了,在使用keep-alive長連接的時候,某個線程會一直被占用,即使中間沒有請求,需要等待到超時才會被釋放(該問題在prefork模式下也存在)。
Apache總是試圖維持一個備用(spare)或是空閑的服務線程池。這樣,客戶端無須等待新線程或新進程的建立即可得到處理。在Unix中,為了能夠綁定80端口,父進程一般都是以root身份啟動,隨後,Apache以較低權限的用戶建立子進程和線程。User和Group指令用於配置Apache子進程的權限。雖然子進程必須對其提供的內容擁有讀權限,但應該盡可能給予他較少的特權。另外,除非使用了suexec ,否則,這些指令配置的權限將被CGI腳本所繼承。
2、Apache的worker模式安裝方法
在編譯安裝Apache的過程中,加入參數--with-mpm=worker即可進行編譯安裝。也可以使用--enable-mpms-shared=all,這樣在編譯的時候會在modules目錄下自動編譯出三個MPM文件的so,然後通過修改httpd.conf配置文件更改MPM即可。
3、Apache的worker模式優缺點
優點:占據更少的內存,高並發下表現更優秀。
缺點:必須考慮線程安全的問題,因為多個子線程是共享父進程的內存地址的。如果使用keep-alive的長連接方式,也許中間幾乎沒有請求,這時就會發生阻塞,線程被掛起,需要一直等待到超時才會被釋放。如果過多的線程,被這樣占據,也會導致在高並發場景下的無服務線程可用。(該問題在prefork模式下,同樣會發生)。
說明:http1.1的keep-alive的長連接方式,是為了讓下一次的socket通信復用之前創建的連接,從而,減少連接的創建和銷毀的系統開銷。保持連接,會讓某個進程或者線程一直處於等待狀態,即使沒有數據過來。
4、Apache的worker模式配置參數說明
<IfModule mpm_worker_module>
StartServers 3 服務啟動時初始的進程數,默認3
MinSpareThreads 75 最小的空閑子進程數,默認75
MaxSpareThreads 250 最大的空閑子進程數,默認250
ThreadsPerChild 25 每個子進程產生的線程數量,默認是25
MaxRequestWorkers 400
限定同一時間內客戶端最大接入的請求數量,默認是400
MaxConnectionsPerChild 0
每個子進程在其生命周期內允許最大的請求數量,如果請求總數已經達到這個數值,子進程將會結束,如果設置為0,子進程將永遠不會結束。將該值設置為非0值,可以防止運行PHP導致的內存泄露。
</IfModule>
Worker模式下所能同時處理的請求總數是由子進程總數乘以ThreadsPerChild 值決定的,應該大於等於MaxRequestWorkers。如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。默認最大的子進程總數是16,加大時 也需要顯式聲明ServerLimit(最大值是20000)。需要註意的是,如果顯式聲明了ServerLimit,那麽它乘以 ThreadsPerChild的值必須大於等於MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則 Apache將會自動調節到一個相應值。
四、Apache的event模式工作原理及相關介紹
1、Apache的event模式工作原理
event是Apache最新的工作模式,它和worker模式很像,不同的是在於它解決了keep-alive長連接的時候占用線程資源被浪費的問題(某些線程因為被keep-alive,掛在那裏等待,中間幾乎沒有請求過來,一直等到超時)。
在event工作模式中,會有一些專門的線程用來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務器的線程,執行完畢後,又允許它釋放。這樣,一個線程就能處理幾個請求了,實現了異步非阻塞。這增強了在高並發場景下的請求處理。
event工作模式在遇到某些不兼容的模塊時,會失效,將會回退到worker模式,一個工作線程處理一個請求。官方自帶的模塊,全部是支持event工作模式的。
event工作模式需要Linux系統(Linux 2.6+)對epoll的支持,才能啟用。需要補充的是HTTPS的連接(SSL),它的運行模式仍然是類似worker的方式,線程會被一直占用,知道連接關閉。部分比較老的資料裏,說event MPM不支持SSL,那個說法是幾年前的說法,現在已經支持了。
2、Apache的event模式安裝方法
在編譯安裝Apache的過程中,加入參數--with-mpm=event即可進行編譯安裝。也可以使用--enable-mpms-shared=all,這樣在編譯的時候會在modules目錄下自動編譯出三個MPM文件的so,然後通過修改httpd.conf配置文件更改MPM即可。
3、Apache的worker模式配置參數說明
<IfModule mpm_event_module>
StartServers 3 服務啟動時初始的進程數,默認3
MinSpareThreads 75 最小的空閑子進程數,默認75
MaxSpareThreads 250 最大的空閑子進程數,默認250
ThreadsPerChild 25 每個子進程產生的線程數量,默認是25
MaxRequestWorkers 400
限定同一時間內客戶端最大接入的請求數量,默認是400
MaxConnectionsPerChild 0
每個子進程在其生命周期內允許最大的請求數量,如果請求總數已經達到這個數值,子進程將會結束,如果設置為0,子進程將永遠不會結束。將該值設置為非0值,可以防止運行PHP導致的內存泄露。
</IfModule>
五、工作模式與web應用的選擇
Apache能更好的為有特殊要求的站點定制。例如,要求 更高伸縮性的站點可以選擇使用線程的 MPM,即 worker 或 event; 需要可靠性或者與舊軟件兼容的站點可以使用 prefork。就使用PHP而言,fastCGI和php-fpm是更推薦的使用模式。
現在的最新瀏覽器,在單個域名下的連接數變得越來越多(通常都是使用keep-alive),主流瀏覽器是2-6個(還有繼續增長趨勢,為了加快頁面的並發下載速度)。高並發場景,會越來越成為Web系統的一種常態。Apache很成熟,同時也背負了比較重的歷史代碼和模塊,因此,在Web系統比較方面,Nginx在不少場景下,表現比起Apache更為出色。
Apache三種工作模式介紹與配置