引子
先來分析一個Yslow 測試的一個頁面的前端性能。
這里所有的請求是指http請求,對于一個請求各個階段的劃分,阻擋->域名解析->建立連接->發(fā)送請求->等待響應(yīng)->接收數(shù)據(jù)。當(dāng)然不是每個請求都要包含所有過程。
在以上測試中,沒有涉及到請求下載資源過程中還有一個部分:TCP請求的鏈接與斷開,而這篇文章正式說這個請求的。
那么http請求和tcp請求是什么關(guān)系呢?簡單點說就是一個tcp請求是比較靠近底層的,在它上面是http之類的應(yīng)用請求,所以可以認為一個tcp請求包括很多個http請求(至于包括多少,apache中可以設(shè)定),同時tcp的鏈接與斷開比http請求的鏈接和斷開更需要消耗掉更多的內(nèi)存資源和時間。
KeepAlive的含義
KeepAlive配置的含義:對于HTTP/1.1的客戶端來說,將會盡量的保持客戶的HTTP連接,通過一個連接傳送多份HTTP請求響應(yīng)。這樣對于客戶端來說,可以提高50%左右的響應(yīng)時間,而于服務(wù)器端來說則降低了更多個連接的開銷。不過這個依賴于客戶端是否想保持連接。IE默認是保持連接的,當(dāng)你打開100個圖片的網(wǎng)站時,IE有可能只打開2個連接,通過這兩個連接傳送數(shù)據(jù),而不是開100個連接。
在 Apache 服務(wù)器中,KeepAlive 是一個布爾值,On 代表打開,Off 代表關(guān)閉,這個指令在其他眾多的 HTTPD 服務(wù)器中都是存在的。
KeepAliveTimeout 為持久連接保持的時間,也就是說,在這此連接結(jié)束后開始計時,多長時間內(nèi)沒有重新發(fā)送HTTP請求,就斷掉連接。默認設(shè)置為5秒,這個值可以大點,但不能太大,否則會出現(xiàn)同時等候過多連接,導(dǎo)致多的內(nèi)存被占用。
KeepAlive的作用
如何謀求網(wǎng)絡(luò)帶寬與服務(wù)器資源之間的平衡。這個要根據(jù)具體情況,具體分析。
那么我們考慮3種情況:
1。用戶瀏覽一個網(wǎng)頁時,除了網(wǎng)頁本身外,還引用了多個 javascript 文件,多個 css 文件,多個圖片文件,并且這些文件都在同一個 HTTP 服務(wù)器上。
2。用戶瀏覽一個網(wǎng)頁時,除了網(wǎng)頁本身外,還引用一個 javascript 文件,一個圖片文件。
3。用戶瀏覽的是一個動態(tài)網(wǎng)頁,由程序即時生成內(nèi)容,并且不引用其他內(nèi)容。
對于上面3中情況,我認為:1 最適合打開 KeepAlive ,2 隨意,3 最適合關(guān)閉 KeepAlive
在 Apache 中,打開和關(guān)閉 KeepAlive 功能,服務(wù)器端會有什么異同呢? 下面看理論分析。
打開 KeepAlive 后,意味著每次用戶完成全部訪問后,都要保持一定時間后才關(guān)閉會關(guān)閉 TCP 連接,那么在關(guān)閉連接之前,必然會有一個Apache 進程對應(yīng)于該用戶而不能處理其他用戶,假設(shè) KeepAlive 的超時時間為 10 秒種,服務(wù)器每秒處理 50個獨立用戶訪問,那么系統(tǒng)中 Apache 的總進程數(shù)就是 10 * 50 = 500 個,如果一個進程占用 4M 內(nèi)存,那么總共會消耗 2G內(nèi)存,所以可以看出,在這種配置中,相當(dāng)消耗內(nèi)存,但好處是系統(tǒng)只處理了 50次 TCP 的握手和關(guān)閉操作。
如果關(guān)閉 KeepAlive,如果還是每秒50個用戶訪問,如果用戶每次連續(xù)的請求數(shù)為3個,那么 Apache 的總進程數(shù)就是 50 * 3= 150 個,如果還是每個進程占用 4M 內(nèi)存,那么總的內(nèi)存消耗為 600M,這種配置能節(jié)省大量內(nèi)存,但是,系統(tǒng)處理了 150 次 TCP的握手和關(guān)閉的操作,因此又會多消耗一些 CPU 資源。
在看看實踐的觀察。
在一組大量處理動態(tài)網(wǎng)頁內(nèi)容的服務(wù)器中,起初打開 KeepAlive功能,經(jīng)常觀察到用戶訪問量大時Apache進程數(shù)也非常多,系統(tǒng)頻繁使用交換內(nèi)存,系統(tǒng)不穩(wěn)定,有時負載會出現(xiàn)較大波動。關(guān)閉了 KeepAlive功能后,看到明顯的變化是: Apache 的進程數(shù)減少了,空閑內(nèi)存增加了,用于文件系統(tǒng)Cache的內(nèi)存也增加了,CPU的開銷增加了,但是服務(wù)更穩(wěn)定了,系統(tǒng)負載也比較穩(wěn)定,很少有負載大范圍波動的情況,負載有一定程度的降低;變化不明顯的是:訪問量較少的時候,系統(tǒng)平均負載沒有明顯變化。
總結(jié)一下:
在內(nèi)存非常充足的服務(wù)器上,不管是否關(guān)閉 KeepAlive 功能,服務(wù)器性能不會有明顯變化;
如果服務(wù)器內(nèi)存較少,或者服務(wù)器有非常大量的文件系統(tǒng)訪問時,或者主要處理動態(tài)網(wǎng)頁服務(wù),關(guān)閉 KeepAlive 后可以節(jié)省很多內(nèi)存,而節(jié)省出來的內(nèi)存用于文件系統(tǒng)Cache,可以提高文件系統(tǒng)訪問的性能,并且系統(tǒng)會更加穩(wěn)定。
KeepAlive配置文件
如果設(shè)置KeepAlive ,找到這個設(shè)置的文件頗為費時,以前版本的大多配置都在httpd.conf文件,現(xiàn)在版本(2.4.2)的apache把不少配置都分離到不同的文件中了,于是,我只好一個文件一個文件的搜索。
...apache/conf/extra/httpd-default.conf
#
# This configuration file reflects default settings for Apache HTTP Server.
#
# You may change these, but chances are that you may not need to.
##
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 60
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5
## UseCanonicalName: Determines how Apache constructs self-referencing
# URLs and the SERVER_NAME and SERVER_PORT variables.
# When set "Off", Apache will use the Hostname and Port supplied
# by the client. When set "On", Apache will use the value of the
# ServerName directive.
#
UseCanonicalName Off
#
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess
#
# ServerTokens
# This directive configures what you return as the Server HTTP response
# Header. The default is 'Full' which sends information about the OS-Type
# and compiled in modules.
# Set to one of: Full | OS | Minor | Minimal | Major | Prod
# where Full conveys the most information, and Prod the least.
#
ServerTokens Full
#
# Optionally add a line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc., but not CGI generated
# documents or custom error documents).
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
# Set to one of: On | Off | EMail
#
ServerSignature Off
#
# HostnameLookuPS: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off
#
# Set a timeout for how long the client may take to send the request header
# and body.
# The default for the headers is header=20-40,MinRate=500, which means wait
# for the first byte of headers for 20 seconds. If some data arrives,
# increase the timeout corresponding to a data rate of 500 bytes/s, but not
# above 40 seconds.
# The default for the request body is body=20,MinRate=500, which is the same
# but has no upper limit for the timeout.
# To disable, set to header=0 body=0
#
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
文件的注釋部分已經(jīng)給出了每個參數(shù)的具體含義,所以這里就沒必要一一解釋了。