1. 程式人生 > 實用技巧 >二、Apache MPM三種工作模式

二、Apache MPM三種工作模式

一、Apache即現階段比較流行的Web服務,是一個多模組化的Web服務,使用簡單,速度快,穩定性好,可以做負載均衡及代理伺服器來使用。

二、Apache有三種工作模式分別是 prefork、work、even

Apache prefork模型

1、prefork介紹

prefork模型,有一個主控制程序,然後生成多個子程序,使用select模型,最大併發1024,每個子程序有一個獨立的執行緒來處理客戶的請求,相對比較佔用記憶體,但是比較穩定,可以設定最大和最小程序數,是最古老的一種模式,也是最穩定的一種模式,適用於訪問量不是很大的場景。有點:穩定 ;缺點:慢、佔用資源,1024個程序不適用於高併發場景。

2、prefork的工作方式

Prefork 工作原理:控制程序Master首先會生成“StartServers”個程序,“StartServers”可以在Apache主配置檔案裡配置,然後為了滿足“MinSpareServers”設定的最小空閒程序個數,會建立一個空閒程序,等待一秒鐘,繼續建立兩個空閒程序,再等待一秒鐘,繼續建立四個空閒程序,以此類推,會不斷的遞迴增長建立程序,最大同時建立32個空閒程序,直到滿足“MinSpareServers”設定的空閒程序個數為止。Apache的預派生模式不必在請求到來的時候建立程序,這樣會減小系統開銷以增加效能,不過Prefork 是基於多程序的模式工作的,每個程序都會佔用記憶體,這樣資源消耗也較高。

3、apache prefork文件說明

一個單獨的控制程序(主httpd程序)負責產生用於監聽和處理連線的子程序,並控制這些子程序的存活週期。httpd主程序總是嘗試保留一些備用或空閒的服務程序,以便能夠隨時處理新流入的請求。這種方式下,客戶端在得到服務前就不用等待httpd fork一個新的子程序。

指令StartServers, MinSpareServers, MaxSpareServers和MaxRequestWorkers調節了父程序如何建立服務子程序。通常情況下,主httpd程序有很好的自我調節能力,絕大多數站點沒有必要去調整這些指令的預設值。對於要處理大於256個併發請求的站點來說,可能需要增大MaxRequestWorkers指令的值,但如果沒有足夠的記憶體,應該減小MaxRequestWorker指令的值以保證不使用swap分割槽而降低整體的效能。

在Unix系統中,父程序通常以root身份執行以便繫結特權80埠,而主httpd的子程序通常以一個低特權的使用者執行。User和Group指令可以設定子程序的身份許可權。執行子程序的使用者必須要對它所服務的內容有讀許可權,但對服務內容之外的其他資源應該儘可能少地擁有許可權。

MaxConnectionsPerChild指令用於控制殺死舊子程序和生成新子程序的頻率。

  1. MaxSpareServers 預設為10。 該指令設定期望的最大空閒子程序數。空閒子程序指的是當前沒有在處理任何請求。如果空閒子程序數比該指令指定的數量還多,則父程序會殺掉多餘的子程序。 只有在非常繁忙的站點上才有必要調整該指令的值。強烈建議不要將該指令的值設定交大。如果嘗試設定該值小於或等於MinSpareServer的值,主httpd程序將自動調整該指令的值為MinSpareServers+1。

  2. MinSpareServers 預設值為5。 該指令設定期望的最小空閒子程序數。空閒子程序指的是當前沒有在處理任何請求。如果空閒子程序數少於該指令指定的值,則父程序會新建立子程序補足缺少的空閒子程序。此時建立空閒子程序的方式:派生一個子程序,等一秒,派生兩個子程序,等一秒,派生4個子程序,依次下去最多到每秒32個子程序,並強制停止派生。 只有在非常繁忙的站點上才有必要調整該指令的值。強烈建議不要將該指令的值設定較大。

Apache worker模型

1、worker介紹

一種多程序和多執行緒混合的模型,有一個控制程序,啟動多個子程序,每個子程序裡面包含固定的執行緒,使用執行緒來處理請求,當執行緒不夠使用時會再啟動一個新的子程序,然後在程序裡面再啟動執行緒處理請求,由於使用了執行緒處理請求,因此可以承受更高的併發。有點:相比prefork 佔用的記憶體較少,可以同時處理更多的請求;缺點:使用keepalive的長連線方式,某個執行緒會一直被佔用。如果過多的執行緒,被這樣佔用,也會導致在高併發場景下無服務執行緒可用。(prefork也有同樣的問題)

2、worker的工作方式

Worker MPM是Apche 2.0版本中全新的支援多程序多執行緒混合模型的MPM,由於使用執行緒來處理HTTP請求,所以效率非常高,而對系統的開銷也相對較低,Worker MPM也是基於多程序的,但是每個程序會生成多個執行緒,由執行緒來處理請求,這樣可以保證多執行緒可以獲得程序的穩定性;

Worker MPM工作原理: 控制程序Master在最初會建立“StartServers”個程序,然後每個程序會建立“ThreadPerChild”個執行緒,多執行緒共享該程序內的資源,同時每個執行緒獨立的處理HTTP請求,為了不在請求到來的時候建立執行緒,Worker MPM也可以設定最大最小空閒執行緒,Worker MPM模式下同時處理的請求=ThreadPerChild*程序數,也就是MaxClients,如果服務負載較高,當前程序數不滿足需求,Master控制程序會fork新的程序,最大程序數不能超過ServerLimit數,如果需要,可以調整這些對應的引數,比如,如果要調整StartServers的數量,則也要調整 ServerLimit的值。

3、apache worker文件說明

一個單獨的控制程序(父程序)負責產生子程序。每個子程序建立固定數量的服務執行緒,數量由ThreadsPerChild指令設定,同時還會額外建立一個監聽執行緒,負責監聽請求並在它們到達的時候將它們交給服務執行緒來處理。(即N個服務執行緒+1個監聽執行緒。)

apache http服務總是嘗試保留一些備用或空閒的服務執行緒池,以便可以隨時處理流入的請求。這種情況下,客戶端在它們的請求被處理前無需等待產生新執行緒。初始化時產生的程序數由指令StartServers指定。在操作期間,父程序會評估所有子程序中所有空閒執行緒的總數,還會新建或殺死子程序使得空閒程序總數在MinSpareThreads和MaxSpareThreads指定的邊界值內。由於程序的自我調節能力很好,很少需要修改該指令的預設值。能處理的最大客戶端併發數(如所有程序中的所有執行緒數)由MaxRequestWorkers指令決定。啟用的最大子程序數計算方式為:MaxRequestWorkers/ThreadsPerChild。

有兩個指令可以硬限制啟用的子程序數和每個子程序中的服務執行緒數,硬限制的數量只能通過完全關閉http server再啟動它來改變。ServerLimit指令硬限制啟用的子程序數,它必須大於或等於MaxRequesetWorkers/ThreadsPerChild。ThreadLimit指令硬限制每個子程序中的服務執行緒數,必須大於或等於ThreadsPerChild的值。

除了啟用的子程序之外,可能還有其他的正在被中斷的子程序,這種子程序中可能還至少有一個服務執行緒正在處理請求。所以,可能線上程總數達到了MaxRequestWorkers的數量時,仍存在正被中斷的子程序。可以通過下面的方式禁止某個單獨的子程序終止行為:

  • 設定MaxConnectionsPerChild值為0。

  • 設定MaxSpareThreads的值等於MaxRequestWorkers的值。

一個典型的worker MPM程序-執行緒的配置大致如下:

ServerLimit     16
StartServers 2
MaxRequestWorkers 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25

在Unix系統中,父程序通常以root身份執行以便繫結特權80埠,而主httpd的子程序通常以一個低特權的使用者執行。User和Group指令可以設定子程序的身份許可權。執行子程序的使用者必須要對它所服務的內容有讀許可權,但對服務內容之外的其他資源應該儘可能少地擁有許可權。此外,除非使用了suexec,否則這兩個指令設定的許可權也會被CGI指令碼繼承。

MaxConnectionsPerChild指令用於控制殺死舊子程序和生成新子程序的頻率。

Apache event模型

1、event介紹

event模式是apache中最新的模式,2012年釋出的apache2.4.x系列正式支援event模型,屬於事件驅動模型(epoll),每個程序響應多個請求,在現在版本里的已經是穩定可用的模式。它和worker模式很像,最大的區別在於,它解決了keepalive場景下,長期被佔用的執行緒的資源浪費問題(某些執行緒因為keepalive,空掛在哪裡等待,中間幾乎沒有請求過來,甚至等到超時)。event MPM中,會有一個專門的執行緒來管理這些keepalive型別的執行緒,當有真是請求過來的時候,將請求傳遞給服務執行緒,執行完畢後,又允許它釋放。這樣增強了高併發場景下的請求處理能力。優點:單執行緒響應多請求,佔用更少的記憶體,高併發下表現更優秀,會有一個專門的執行緒來管理keep-alive型別的執行緒,當有真實請求過來的時候,將請求傳遞給服務執行緒,執行完畢後,又允許它釋放;缺點:沒有執行緒安全控制。

2、event工作方式

event工作模式是基於程序、執行緒混合的worker模式的。一個單獨的控制程序(父程序)負責生成子程序,每個子程序建立由固定數量的服務執行緒,服務執行緒數由ThreadsPerChild指令設定,同時還建立一個監聽執行緒,負責監聽請求並在它們到達的時候將它們交給服務執行緒來處理。(即N個服務執行緒+1個監聽執行緒。)

執行時的配置指令和worker模式的指令完全相同,除了AsyncRequestWorkerFactor指令。

它和 worker模式很像,最大的區別在於,它解決了 keep-alive 場景下 ,長期被佔用的執行緒的資源浪費問題(某些執行緒因為被keep-alive,掛在那裡等待,中間幾乎沒有請求過來,一直等到超時)。 event MPM中,會有一個專門的執行緒來管理這些 keep-alive 型別的執行緒,當有真實請求過來的時候,將請求傳遞給服務執行緒,執行完畢後,又允許它釋放。這樣,一個執行緒就能處理幾個請求了,實現了非同步非阻塞。 event MPM在遇到某些不相容的模組時,會失效,將會回退到worker模式,一個工作執行緒處理一個請求。官方自帶的模組,全部是支援event MPM的。

這種MPM嘗試修復http中的"長連線問題"。當客戶端完成了第一次請求後,可以繼續保持它的連線不被關閉,以便之後可以使用相同的套接字傳送其他的請求,而且這樣可以節省多次建立TCP連線帶來的大量消耗。但是,傳統的apache httpd會保留那個負責處理請求的子程序或執行緒來等待客戶端隨後可能傳送的請求,這不免帶來了它自身的缺陷:資源浪費且"佔著茅坑不拉屎"。為了解決這種問題,event MPM在每個子程序中使用一個專門的監聽執行緒,不僅負責監聽套接字,還負責處理所有處於長連線狀態的套接字,這些套接字都是已經被所有handler和協議過濾器(通過過濾器,可以修改請求、待響應內容)處理完畢後的套接字,它們只剩下一件事沒完成:傳送資料給客戶端。