apache 的工做模式

apache有幾種工做模式?怎麼查看和修改apache的工做模式? php

apache的工做模式有:beos,event,worker,prefork,mpmt_os2。 mysql

在linux(centos)下使用#http –l 命令能夠查看當前使用的工做模式。也可使用#apachectl -l命令。看到的prefork.c,說明使用的prefork工做模式。能夠在編譯的時候使用#–with-mpm=prefork對應的工做模式名稱來修改工做模式。beos工做模式(跟linux關係不大,或者暫時用不上) linux

在Beos系統上的工做模式,使用一個單獨的控制線程來建立和控制處理請求的工做線程。
event工做模式(不太穩定,或者說暫時用不上)

event模式因爲把服務進程從連接中分離出來,在開啓KeepAlive場合下相對worker模式可以承受的了更高的負載。event模式爲 worker開發的變種模式,配置以及指令與worker徹底相同。不過event模式不能很好的支持https的訪問,有時還會出現一系列的問題。 sql

worker工做模式(與php配合很差,或者說暫時用不上)
worker模式因爲使用線程來進行處理請求,因此可以處理海量請求,而系統資源的開銷要小於基於進程的服務器。同時worker模式也使用了多進程,每一個進程又有着多個線程,以得到基於進程服務器的穩定性。
mpmt_os2工做模式(不多用,或者說暫時用不上)
mpmt_os2是專門針對OS/2優化過的混合多進程多線程多路處理模塊(MPM) 。
prefork工做模式(本篇文章的主角,使用最多並且最穩定的工做模式)
prefork工做模式是linux下apache安裝時候的默認工做模式,是使用最廣泛的工做模式。爲了可以簡單的明白他的工做原理,下面是一個假設:
有一臺正在運行的apache服務器,用戶A訪問該apache的時候apache創建一個新的進程1處理用戶A的請求。
這時又有一個用戶B訪問該apache,apache又創建一個新的進程2處理用戶B的請求。
後來又有用戶C,D,E訪問該apache,apache又創建三個進程3,4,5處理他們的請求。
若是每當一個新用戶訪問該apache,apache再創建一個新的進程處理用戶的請求,是否是太慢了呢?
因此apache的prefork模式在apache第一次啓動的時候就創建5個進程,等待用戶的鏈接請求,有一個用戶訪問,就有一個進程處理他的請求。那麼若是有5個用戶同時訪問apache,apache第一次創建的5個進程所有用光了,因此apache就再重新在創建5個進程,等待下一批用戶的請求。
prefork模式會根據服務器的硬件狀況,設定apache最多隻能同時創建256個進程。再多的請求就只能等待前面的進程處理完畢在進行處理。
假設完畢!
上面的假設就是prefork模式的工做原理。可是上面假設中具體的數字不是定死的,而是經過prefork模式的配置來設置的。下面是http.conf中的配置信息。 apache

StartServers apache啓動時候默認開始的進程數 centos

MinSpareServers 最小的閒置進程數 apache在沒有用戶訪問時候有5個閒置的進程,若是有一個用戶訪問網站。則閒置的進程就只有4個,這個值小於MinSpareServers,因此 apache就以第一秒1個進程,第二秒2個進程,第三秒4個進程的速度新建空閒進程。直到大於等於MinSpareServers個空閒進程才結束。 瀏覽器

MaxSpareServers 最大的閒置進程數 ServerLimit 最大的進程總數 MaxClients 最大的進程總數 apache在沒有用戶訪問時候有5個閒置的進程,若是有5個用戶同時訪問網站。則閒置的進程就只有0個,這個值小於 MinSpareServers,因此apache就以第一秒1個進程,第二秒2個進程,第三秒4個進程的速度新建空閒進程。直到大於等於 MinSpareServers個空閒進程才結束。在這個例子中直到第三秒,一共生成1+2+4個進程才能知足大於等於MinSpareServers的 要求。後來這5個用戶訪問完apache,訪問結束,關閉瀏覽器。因此apache就有了5+7個空閒的進程。這時空閒的進程比較多,apache就開始 關閉一些進程,直到知足小於MaxSpareServers個空閒進程才結束。若是該值小於MinSpareServers則apache默認將該值設置 成MinSpareServers+1。 服務器

ServerLimit 這個參數是控制apache的進程總數的,那爲何會有兩個參數控制apache的進程總數呢?這個參數在apache1的時代是沒有的,由於那個時候有 個256M內存的服務器就很厲害了。後來apache2的時代到來,服務器的硬件也獲得升級。不少服務器都是4G內存,還有不少比4G內存大的服務器出 現。apache1的時代只有一個MaxClients參數控制進程總數就夠了,而這個參數最大值是256定死了。可是到了apache2的時代必須調整 ServerLimit值大於256才能使MaxClient支持大於256的值。 多線程

MaxClients apache最大的進程數。apache1的時代只有一個MaxClients參數控制進程總數就夠了,而這個參數最大值是256定死了。可是到了apache2的時代必須調整ServerLimit值大於256才能使MaxClient支持大於256的值。 併發

MaxRequestsPerChild 每一個進程處理的最多請求數 apache在沒有用戶訪問的時候有5個空閒進程。當一個用戶訪問網站,訪問完又離開。則apache的第一個進程就處理了一個請求,重新進入閒置狀態。 再有一個用戶訪問網站,訪問完後離開。則apache的第一個進程就處理了1+1個請求。這樣繼續訪問3998個用戶,這個進程就處理了4000個請求, 以後就自動關閉這個進程。這個時候apache就只有4個限制的進程,小於MinSpareServers值因此apache從今創建一個空閒進程。至於 爲何處理完4000個請求就要關閉這個進程呢?答案之一:爲了防止內存的泄露。

首先查看apache第一次啓動時候的空閒進程:

 

linux(centos)下查看apache的進程可使用#ps -ef|grep httpd命令,查看apache進程的內存使用狀況可使用#ps –U apache –u apache u命令

#service httpd restrat:重啓apache,初始化進程

#ps -ef|grep httpd:用戶名爲apache的纔是apache用於處理用戶請求的進程

#ps –U apache –u apache u:查看用戶名爲apache的進程(即apache爲了處理用戶請求而創建的進程詳情)


1,apache是嚴格按照prefork模式的配置參數來進程分配和管理的。不像網上有些文章那樣修改了某個值,apache不起做用。只能說您改的不對,或者說您對上面的內容還不夠理解。

2,MaxClients值就是apache的最大進程數。不像網上有些文章說的這個值越大越好(有的文章既然推薦該值爲4000),您能夠從上面的進程 圖中看到apache的每一個進程的%MEM(內存佔用百分比)值爲0.5%左右。因此這個值的具體設置的最大數位:100/0.5 = 200。而這也只是在這個服務器只有一個apache的狀況下。若是服務器有其餘程序須要佔用內存(好比mysql)這個值要小於200。你總不能把操做 系統的全部內存都給apache吧?

3,每一個瀏覽器是一個用戶,每一個用戶就是一條進程。明白意思了吧?個人這臺服務器的併發量只有200。就是說個人這臺服務器只能支持同時200個用戶訪 問,再多的用戶訪問就只能是等待。或者說我這臺服務器只支持200個瀏覽器的訪問。關於服務器的併發我會在下面一片文章中詳細講解。


4,200的併發量很小嗎?要知道apache處理數據的速度是至關快的。一條正常的首頁訪問可能就一秒鐘處理完畢。因此在假想的狀態下,個人這臺 服務器,每分鐘能夠訪問60*200=12000個用戶。天天能夠訪問12000*60*24=17280000個用戶的訪問。這固然是在徹底飽和的訪問 狀態的假想數據。下一篇文章我會詳細講解網站併發,請求,連擊等內容。

5,若是訪問的用戶數大於MaxClients的數,多出的用戶不會馬上斷掉鏈接,仍是會創建TCP鏈接。只不過會等待前面的用戶處理完在獲得相應。在php.ini,http.conf,操做系統設定的超時時間內得不到相應纔會斷掉鏈接。


不是全部請求都會創建鏈接,限制是linux操做系統上,或者說apache所在的操做系統。既然瀏覽器能夠發起無數個請求,那麼能不能成功創建鏈接就是服務端的事情。那麼究竟是apache限制了最大的鏈接數仍是linux限制了最大的鏈接數?仍是PHP限制了最大鏈接數?或者說是mysql限制了最大鏈接數?答案是linux限制了瀏覽器和apache之間的最大鏈接數。下面就通具體的測試來回答。

首先咱們假設是apache限制了最大鏈接數。打開apache的httpd.conf文件。找了半天發現只有下這一段跟最大鏈接數有點關係。


對於上圖的參數不明白能夠查看上一篇文章從工做模式講解apache進程和用戶請求的關係

按照如上圖同樣設置後進行測試。

參數:

StartServers
1

MinSpareServers
1

MaxSpareServers
2

ServerLimit
256

MaxClients
3

MaxRequestPerChild
4000

測試環境:

服務器
虛擬機上的centOS4.5

客戶端
本機上的IE瀏覽器

服務器地址
192.168.212.128

客戶端地址
192.168.212.1

訪問文件

<?php
for($i = 0;$i <= 10;$i++){
echo date('H:i:s',time());
echo '<br/>';
sleep(10);
}
?>

經過10個IE瀏覽器模擬10個用戶同時對apache發起請求:(基本同時訪問)

經過netstat命令能夠看到這10個請求都創建了鏈接。

#netstat -nt|grep –i ’80′


再看看apache的狀況:

#ps –U apache u


看到了吧?第一次同時訪問時候apache只啓用了3個進程處理前三個用戶的請求。

過10*10秒以後再看看連服務器的鏈接狀態和apache進程狀態。


能夠看到第一批3個用戶的請求處理完畢,3個鏈接狀態爲TIME_WAIT。能夠從前面的IE瀏覽器打印的內容看到最後的響應時間爲18:20:35。要知道這個時候另外7個頁面仍是在載入中。能夠看到這7個瀏覽器的進度條在走,而不是沒有響應,也沒有提示403等錯誤。


看到apache的進程仍是隻有3個,由於上面的MaxClients=3限制了最大的進程數爲3。而不會開啓多餘的進程處理請求。

再看看過了2*10*10秒後的狀態。


能夠看到第一批3個用戶的鏈接已經斷開,第二批3個用戶的請求已經處理完畢,正在準備斷開鏈接,TIME_WAIT會在2*SML秒後進入 CLOSED狀態。即斷開鏈接。能夠從前面IE瀏覽器打印的內容看到開始響應時間爲18:20:52。最後響應時間爲18:22:32。第一批和第二批瀏 覽器已經顯示完畢,剩下的4個瀏覽器狀態是正在載入中,能夠看到進度條在走動。


看到apache的進程仍是隻有3個。

再看看過了3*10*10秒後的狀態。


能夠看到這時前面的6個鏈接都已經斷開,第三批瀏覽器的請求已經處理完畢正在準備斷開鏈接,TIME_WAIT會在2*SML秒後進入CLOSED 狀態。即斷開鏈接。能夠從前面IE瀏覽器打印的內容看到開始響應時間爲18:22:42。最後響應時間爲18:24:22。第一批,第二批,第三批瀏覽器 已經顯示完畢,剩下的1個瀏覽器狀態是正在載入中,能夠看到進度條在走動。


看到apache的進程仍是隻有3個。

再看看過了4*10*10秒後的狀態。


能夠看到這時前面的9個鏈接都已經斷開,第四批瀏覽器的請求已經處理完畢正在準備斷開鏈接,TIME_WAIT會在2*SML秒後進入CLOSED 狀態。即斷開鏈接。能夠從前面IE瀏覽器打印的內容看到開始響應時間爲18:24:25。最後響應時間爲18:26:05。第一批,第二批,第三批,第四 批瀏覽器所有顯示完畢。


能夠看到apache的進程已經減小爲2個。

測試獲得的結論

上面的測試能夠看到,瀏覽器與apache之間的最大TCP鏈接數不是有apache限制的。apache工做模式中MaxClients等參數只 是限制了apache的進程數量,並無限制瀏覽器和apache的鏈接數量。就算apache的進程已經到達MaxClients的最大數,其餘瀏覽器 仍是能夠訪問。並且訪問也不會拒絕,只是在等待apache的進程將前面的請求處理完,再處理這些沒有響應的請求。

爲何apache不能限制最大的TCP鏈接數呢?答案:TCP鏈接是在鏈路層,apache是基於http協議的在應用層。

下面看看linux是怎麼限制TCP鏈接的最大數的。

首先使用sysctl -a命令看看linux下面的系統配置參數。

#sysctl –a


往下翻翻能夠看到


還有


看到這麼多系統配置參數,是否是有個參數能夠控制TCP的最大鏈接數呢?

找了好久,沒有發現能夠直接控制TCP最大鏈接數的參數,每一個鏈接成立之後linux都會對其進行維護(而且建立維護文件,linux的防火牆就是 根據這個文件的)。發現有個參數ip_conntrack_max就是這個維護文件最大數。(可使用modprobe ip_conntrack開始這個參數。可使用#less /proc/net/ip_conntrack |wc –l 查看當前已經創建的該文件數,鏈接斷開後這個文件也會關閉)

#sysctl -a|grep ip_conntrack_max


雖然看到兩個,可是這兩個文件是同步的,修改後會自動同步。

咱們把它的值修改成1,雖然有點極端,可是能夠很好解釋爲很麼是linux限制了瀏覽器的最大TCP鏈接數。

#echo 1 > ip_conntrack_max


使用兩個IE瀏覽模擬2個用戶同時訪問apache。使用netstat命令查看。

#netstat -nt|grep –i ’80′


看到問題了吧。只有一個鏈接,第二個訪問的瀏覽根本就沒有反應。

測試獲得的結論

在咱們把ip_conntrack_max設置爲1的時候,瀏覽器不敢發送多少請求,linux只會和它創建一個鏈接。

那麼linux沒有專門的值來控制TCP鏈接的最大數呢?有,只不是linux把個限制的條件細化了。好比:同時能夠創建多少CLOSE_WAIT 狀態的鏈接數,同時能夠創建多少個TIME_WAIT狀態的鏈接數,等等等。因此想要控制apache的最大鏈接數,須要經過配合這些數據進行組合。

總結

若是認真讀完上面的內容,會的到下面的結論。

1,用戶的瀏覽器能夠對apache發起N個請求。N的數值可能會很大。

2,只有M(M小於N)個請求會跟apache創建鏈接(只是創建鏈接,並非處理)。而這個M的值是由linux服務器控制。linux會根據硬件的狀況會給出默認值。咱們能夠經過各個參數的組合來計算最後的TCP鏈接數的最大限制。

3,只有P(P小於M)個鏈接會獲得apache的處理。apache會創建P個進程處理這P個鏈接。這個P的值是apache的ClientMax等參數控制的。

相關文章
相關標籤/搜索