一、http的基礎知識php
http是一個請求——響應模式的典型範例,即客戶端向服務器發送一個請求信息,服務器響應這個信息。
css
在老的http版本中:html
每個請求都建立一個TCP鏈接,當一次請求被響應後,tcp四次揮手,鏈接斷開。
sql
這個模式的優勢:數據庫
簡單,易實現,易理解,且知足無鏈接的特色。apache
這個模式的缺點:瀏覽器
效率低。服務器
HTTP /1.0併發
在這個版本的協議上,若是客戶端瀏覽器支持Keep-Alive,那麼就在HTTP請求頭部添加一個Connection:Keep-Alive,當服務器收到附帶Connection:Keep-Alive的請求,也會在響應頭部添加一個一樣的字段來使用Keep-Alive。這樣一來,客戶端和服務器端之間的TCP鏈接就會保持,不會斷開(超過Keep-Alive規定的時間,意外斷電等狀況外),當客戶端發送另一個到這個服務器的請求仍是會使用這個已經創建的鏈接。tcp
HTTP/1.1
在HTTP/1.1版本中,官方規定的Keep-Alive使用標準和在HTTP/1.0版本中有些不一樣,默認狀況下所在HTTP1.1中全部鏈接都被保持,除非在請求頭或響應頭中指明要關閉:Connection: Close這也就是爲何Connection: Keep-Alive字段再沒有意義的緣由。另外,還添加了一個新的字段Keep-Alive:,由於這個字段並無詳細描述用來作什麼,可忽略它。
Not reliable(不可靠)
HTTP是一個無狀態協議,這意味着每一個請求都是獨立的,Keep-Alive沒能改變這個結果。另外,Keep-Alive也不能保證客戶端和服務器之間的鏈接必定是活躍的,在HTTP1.1版本中也如此。惟一能保證的就是當鏈接被關閉時你能獲得一個通知,因此不該該讓程序依賴於Keep-Alive的保持鏈接特性,不然會有意想不到的後果
Keep-Alive和POST
在HTTP1.1細則中規定了在一個POST消息體後面不能有任何字符,還指出了對於某一個特定的瀏覽器可能並不遵循這個標準(好比在POST消息體的後面放置一個CRLF符)。而據我所知,大部分瀏覽器在POST消息體後都會自動跟一個CRLF符再發送,如何解決這個問題呢?根據上面的說明在POST請求中禁止使用Keep-Alive,或者由服務器自動忽略這個CRLF,大部分服務器都會自動忽略,可是在未經測試以前是不可能知道一個服務器是否會這樣作。
容易犯的誤區:
一、HTTP是一個無狀態的面向鏈接的協議,無狀態不表明HTTP不能保持TCP鏈接,更不能表明HTTP使用的是UDP協議(無鏈接)
二、從HTTP/1.1起,默認都開啓了Keep-Alive,保持鏈接特性,簡單地說,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接
三、Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間
問題現象: 一個JSP頁面,竟然要耗時40多秒。網頁中有大量的圖片的CSS
問題解決: 緣由也找了半天,原來Apache配置裏面,把Keep-Alive的開關關閉了。這個是個大問題,工程師爲何要關閉它,原來他考慮的太簡單了,咱們知道Apache適合處於短鏈接的請求,處理時間越短,併發數才能上去,原來他是這麼考慮,可是沒有辦法,只能這樣了,仍是打開Keep-Alive開關吧。
固然,不是全部的狀況都設置KeepAlive爲On。
下面的文字總結比較好:
在使用apache的過程當中,KeepAlive屬性我一直保持爲默認值On,其實,該屬性設置爲On仍是Off仍是要具體問題具體分析的,在生產環境中的影響仍是蠻大的。
KeepAlive選項到底有什麼用處?若是你用過Mysql ,應該知道Mysql的鏈接屬性中有一個與KeepAlive 相似的Persistent Connection,即:長鏈接(PConnect)。該屬性打開的話,可使一次TCP鏈接爲同一用戶的屢次請求服務,提升了響應速度。
好比不少網頁中圖片、CSS、JS、Html都在一臺Server上,當用戶訪問其中的Html網頁時,網頁中的圖片、Css、Js都構成了訪問請求,打開KeepAlive 屬性能夠有效地下降TCP握手的次數(固然瀏覽器對同一域下同時請求的圖片數有限制,減小域名解釋的開銷),減小httpd進程數,從而下降內存的使用(假定prefork模式)。MaxKeepAliveRequests 和KeepAliveTimeOut 兩個屬性在KeepAlive =On時起做用,能夠控制持久鏈接的生存時間和最大服務請求數。
不過,上面說的只是一種情形,那就是靜態網頁居多的狀況下,而且網頁中的其餘請求與網頁在同一臺Server上。當你的應用動態程序(好比:php )居多,用戶訪問時由動態程序即時生成html內容,html內容中圖片素材和Css、Js等比較少或者散列在其餘Server上時,KeepAlive =On反而會下降Apache 的性能。爲何呢?
前面提到過,KeepAlive =On時,每次用戶訪問,打開一個TCP鏈接,Apache 都會保持該鏈接一段時間,以便該鏈接能連續爲同一client服務,在KeepAliveTimeOut還沒到期而且MaxKeepAliveRequests還沒到閾值以前,Apache 必然要有一個httpd進程來維持該鏈接,httpd進程不是廉價的,他要消耗內存和CPU時間片的。假如當前Apache 每秒響應100個用戶訪問,KeepAliveTimeOut=5,此時httpd進程數就是100*5=500個(prefork 模式),一個httpd進程消耗5M內存的話,就是500*5M=2500M=2.5G,誇張吧?固然,Apache 與Client只進行了100次TCP鏈接。若是你的內存夠大,系統負載不會過高,若是你的內存小於2.5G,就會用到Swap,頻繁的Swap切換會加劇CPU的Load。
如今咱們關掉KeepAlive ,Apache 仍然每秒響應100個用戶訪問,由於咱們將圖片、js、css等分離出去了,每次訪問只有1個request,此時httpd的進程數是100*1=100個,使用內存100*5M=500M,此時Apache 與Client也是進行了100次TCP鏈接。性能卻提高了太多。
總結
一、當你的Server內存充足時,KeepAlive =On仍是Off對系統性能影響不大。
二、當你的Server上靜態網頁(Html、圖片、Css、Js)居多時,建議打開KeepAlive 。
三、當你的Server多爲動態請求(由於鏈接數據庫,對文件系統訪問較多),KeepAlive 關掉,會節省必定的內存,節省的內存正好能夠做爲文件系統的Cache(vmstat命令中cache一列),下降I/O壓力。
PS:當KeepAlive =On時,KeepAliveTimeOut的設置其實也是一個問題,設置的太短,會致使Apache 頻繁創建鏈接,給Cpu形成壓力,設置的過長,系統中就會堆積無用的Http鏈接,消耗掉大量內存,具體設置多少,能夠進行不斷的調節,因你的網站瀏覽和服務器配置而異。
減小域名解釋的開銷對於HTTP/1.0來講能夠充分利用瀏覽器默認最大併發鏈接數比HTTP/1.1多的好 處,實現不增長新域名的開銷而更高的並行下載,減小域名解釋的開銷(注:IE 6,7在HTTP/1.0中默認最大併發鏈接數爲4,在HTTP/1.1中默認最大併發鏈接數爲2,IE8都爲6,Firefox2在HTTP/1.0中 默認最大併發鏈接數爲2 在HTTP/1.1中默認最大併發鏈接數爲8,firefox 3默認都是6),根據10年7月Google索引的42億個網頁的統計報告,每張網頁裏包含29.39個圖片,7.09個外部腳本,3.22個外部CSS 樣式表,若是設置了Keep-Alive而且合理控制Keep-Alive TimeOut這個參數能夠大量的節約鏈接的開銷,提升相應速度。若是設置很差,在大併發的狀況小,因維持大量鏈接而使服務器資源耗盡,而對於目前國內大 部分的用戶使用的仍是IE6,7的狀況下關閉Keep-Alive能夠充分利用瀏覽器默認最大併發鏈接數的好處實現不增長額外的開銷頁面快速的展現。