WEB性能(4)--HTTP 1.x

一、HTTP 1.x介紹

HTTP 1.0的優化策略非常簡單,就一句話:升級到HTTP 1.1!

改進HTTP的性能是HTTP 1.1工作組的重要目標,後來HTTP1.1頁引入了大量增強性能的特性:

  1. 持久化連接以支持連接重用;
  2. 分塊傳輸編碼以支持流式相應;
  3. 請求管道以支持並行請求處理;
  4. 字節服務以支持基於範圍的資源請求;
  5. 改進的更好的緩存機制。

在《高性能網站建設指南》中有14條規則,其中有6條是針對網絡的:

  1. 減少DNS查詢

    每次域名解析都需要一次網絡往返,增加請求延遲,在查詢期間會阻塞請求。

  2. 減少HTTP請求

    任何請求優化都不如沒有請求塊。

  3. 使用CDN

    從地理位置上把數據放到更接近用戶的地方,可以顯著減少每次TCP連接的網絡延遲。

  4. 添加Expires首部並配置ETag標籤

    緩存相關資源,避免重複請求每個頁面中相同的數據。

  5. Gzip資源

    所有文本資源都應該使用Gzip壓縮。

  6. 避免HTTP重定向

    HTTP重定向極其耗時,特別是把客戶端重定向到一個完全不同的域名下,還會導致額外的DNS查詢。

二、持久連接

HTTP1.1的一個主要改進就是引入了持久連接。

每個TCP連接開始都有三次握手,要經歷一次客戶端與服務器間完整的一次往返。此後會因爲HTTP請求和響應的兩次通信而至少引發另一次往返。最後還要加上服務器處理時間,才能得到每次請求的總時間。

服務器處理時間無法預測,因爲這個時間因資源和後端硬件而異,不過,這裏的重點其實是由一個新TCP連接發送的HTTP請求所花的總時間,最少等於兩次網絡往返的時間:一次用於握手,一次用於請求和響應。這是所有非持久HTTP會話都要付出的規定時間成本。服務器處理速度越快,固定延遲對每個網絡請求總時間的影響就越大。

添加對HTTP持久連接的支持,就可以避免第二次TCP連接時的三次握手、消除另一次TCP慢啓動的往返,節約整整一次網絡延遲。

三、HTTP管道

持久HTTP可以讓我們重用已有的連接來完成多次應用請求,但是多次請求必須嚴格滿足先進先出(FIFO)的隊列順序:發送請求,等待響應完成,再發送客戶端隊列中的下一個請求。HTTP管道是一個很小但對上述工作流卻非常重要的一次優化。管道可以讓我們把FIFO隊列從客戶端(請求隊列)遷移到服務器(響應隊列)。

我們來理解一下這樣做的好處。首先,服務器處理完第一次請求後,會發生一次完整的往返:先是響應回傳,接着是第二次請求。在此期間服務器空閒。如果服務器能在處理完第一次請求後,立即開始處理第二次請求呢?甚至,如果服務器可以並行或在多線程上或者使用多個工作進程,同時處理兩個請求呢?

通過儘早分派請求,不被每次響應阻塞,可以再次消除額外的網絡往返。這樣就從非持久連接狀態下的每個請求兩次往返,變成了請求隊列只需要兩次網絡往返。

HTTP管道的好處,主要就是消除了發送請求和響應的等待時間。這種並行處理請求的能力對提升應用性能的幫助非常大。

可惜的是,當我們想要採取這個優化措施時,發現了HTTP1.x協議的一些侷限性。HTTP1.x只能嚴格串行的返回響應。特別是,HTTP1.x不允許一個連接上的多個響應數據交錯到達(多路複用),因而一個響應必須完全返回後,下一個響應纔會開始傳輸。

實踐中部署HTTP管道的最佳途徑,就是在客戶端和服務器間使用安全通道(HTTPS)。這樣,就能可靠的避免那些不理解或不支持管道的中間代理的干擾。

四、使用多個TCP連接

由於HTTP1.x不支持多路複用,瀏覽器可以不假思索的在客戶端排隊所有HTTP請求,然後通過一個持久連接,一個接一個的發送這些請求。然而,這種方式在實踐中太慢。實際上,瀏覽器開發商沒有別的辦法,只能允許我們並行打開多個TCP會話,一般是6個。

五、域名分區

HTTP1.x協議的一項空白強迫瀏覽器開發商引入並維護着連接池,每個主機最多6個TCP流。好的一方面是對這些連接的管理工作都是瀏覽器完成。不好的一方面是,6個並行的連接可能還是不夠用。

實際上,何必把自己只限制在一個主機上呢?我們不必只通過一個主機提供所有的資源,而是可以手工將所有資源分散到多個域名。由於主機名不一樣了,就可以突破瀏覽器的連接限制,實現更高的並行能力。

當然,天下沒有免費的午餐,域名分區也不例外:每個新主機名都要求有一次額外的DNS查詢,每多一個套接字都會多消耗兩端的一些資源。

六、度量和控制協議開銷

HTTP0.9當初就是一個簡單的只有一行的ASCII請求,用於取得一個超文本文檔。HTTP1.0增加了請求和響應頭部,以便雙方可以交換請求和響應的元信息。今天,每個瀏覽器發起的HTTP請求,都會攜帶額外500-800字節的HTTP元數據:用戶代理字符串、很少改變的接收和傳輸首部、緩存指令等等。如果再加上Cookie進行會話管理,綜合到一起,所有這些未經壓縮的HTTP元數據通常會給每個HTTP請求增加幾千字節的協議開銷。

七、連接與拼合

最快的請求就是不用請求。不管使用什麼協議,也不管是什麼類型的應用,減少請求次數總是最好的性能優化手段。可是,如果如果無法減少請求數量,那麼對HTTP1.x而言,可以考慮把多個資源捆綁到一起,通過一次網絡請求獲取:

連接:把多個JavaScript或CSS文件組合成一個文件。

拼合:把多張圖片組合成一個圖片。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章