1. HTTP發展歷史

HTTP(超文本傳輸協議,HyperText Transfer Protocol)是建立在TCP協議之上的一種應用層網路協議。默認使用80埠,建立之初目的是為了將超文本標記語言(HTML)文檔從Web伺服器傳送到客戶端的瀏覽器。WEB2.0以後,頁面變得越來越複雜,以及ajax的出現提供了一種向服務端獲取數據的新方式,這些推動著HTTP協議不斷擴展功能、不斷優化性能:

  • HTTP/0.9:1991年發布,極其簡單,只有一個get命令;
  • HTTP/1.0:1996年5月發布,增加了大量內容;
  • HTTP/1.1:1997年1月發布,進一步完善HTTP協議,是目前最流行的版本;
  • SPDY :2009年穀歌發布SPDY協議,主要解決HTTP/1.1效率不高的問題;
  • HTTP/2 :2015年借鑒SPDY的HTTP/2發布。

2. HTTP的優化

HTTP協議建立在TCP協議之上,所以HTTP協議的瓶頸及其優化技巧都是基於TCP協議本身的特性,比如TCP的三次握手和四次揮手以及每次建立連接帶來的RTT延遲時間。

影響一個HTTP網路請求的因素主要有兩個:帶寬和延遲:

  • 帶寬:網路帶寬是指單位時間內傳輸的數據量,是數據的傳輸能力。現在網路基礎建設較為完善,基本不用擔心帶寬影響網速,所以目前影響HTTP網路請求性能的就是延遲了。
  • 延遲:1. 瀏覽器阻塞(head of line blocking):瀏覽器會因為一些原因阻塞請求。瀏覽器對於同一個域名,同時只能有 6個連接(這個根據瀏覽器內核不同可能會有所差異),超過瀏覽器最大連接數限制,後續請求就會被阻塞。這也是為何一些站點會有多個靜態資源 CDN 域名的原因之一。2. DNS查詢(DNS Lookup):將域名解析為IP就是DNS查詢,一般使用DNS緩存來減少這個時間。3. 建立連接(Initial connection):HTTP 是基於 TCP 協議的,瀏覽器最快也要在第三次握手時才能攜帶 HTTP 請求報文,達到真正的建立連接,但是這些連接無法復用會導致每次請求都經歷三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對文件類大請求影響較大。

3. HTTP/1.1 和 HTTP/1.0 的區別

1. 緩存處理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since來作為緩存判斷的標準;HTTP/1.1 引入了更多的緩存控制策略:Cache-ControlEtag/If-None-Match等。

2. 錯誤狀態管理:HTTP/1.1新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示伺服器上的某個資源被永久性的刪除。

3. 範圍請求:HTTP/1.1在請求頭引入了range頭域,它允許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和連接,支持斷點續傳。

4. Host頭:HTTP1.0中認為每臺伺服器都綁定一個唯一的IP地址,因此,請求消息中的URL並沒有傳遞主機名(hostname)。但隨著虛擬主機技術的發展,在一臺物理伺服器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。有了Host欄位,就可以將請求發往同一臺伺服器上的不同網站,為虛擬主機的興起打下了基礎。

5. 持久連接:HTTP/1.1 最大的變化就是引入了持久連接(persistent connection),在HTTP/1.1中默認開啟 Connection: keep-alive,即TCP連接默認不關閉,可以被多個請求復用。

客戶端和伺服器發現對方一段時間沒有活動,就可以主動關閉連接。不過,規範的做法是,客戶端在最後一個請求時,發送Connection: close,明確要求伺服器關閉TCP連接。客戶端和伺服器發現對方一段時間沒有活動,就可以主動關閉連接。不過,規範的做法是,客戶端在最後一個請求時,發送Connection: close,明確要求伺服器關閉TCP連接。

6. 管道機制:HTTP/1.1中引入了管道機制(pipelining),即在同一個TCP連接中,客戶端可以同時發送多個請求。

4. HTTP/1.1的缺點

HTTP/1.1 的持久連接和管道機制允許復用TCP連接,在一個TCP連接中,也可以同時發送多個請求,但是所有的數據通信都是按次序完成的,伺服器只有處理完一個回應,才會處理下一個回應。比如客戶端需要A、B兩個資源,管道機制允許瀏覽器同時發出A請求和B請求,但伺服器還是按照順序,先回應A請求,完成後再回應B請求,這樣如果前面的回應特別慢,後面就會有很多請求排隊等著,這稱為「隊頭阻塞(Head-of-line blocking)」

5. HTTP/2

HTTP/2以Google發布的SPDY協議為基礎,於2015年發布。它不叫HTTP/2.0,因為標準委員會不打算再發布子版本了,下一個新版本將是HTTP/3。HTTP/2協議只在HTTPS環境下才有效,升級到HTTP/2,必須先啟用HTTPS。HTTP/2解決了HTTP/1.1的性能問題,主要特點如下:

1. 二進位分幀:HTTP/1.1的頭信息是文本(ASCII編碼),數據體可以是文本,也可以是二進位;HTTP/2 頭信息和數據體都是二進位,統稱為「幀」:頭信息幀和數據幀;

2. 多路復用(雙工通信):通過單一的 HTTP/2 連接發起多重的請求-響應消息,即在一個連接裏,客戶端和瀏覽器都可以同時發送多個請求和響應,而不用按照順序一一對應,這樣避免了「隊頭堵塞」。HTTP/2 把 HTTP 協議通信的基本單位縮小為一個一個的幀,這些幀對應著邏輯流中的消息。並行地在同一個 TCP 連接上雙向交換消息。

3. 數據流:因為 HTTP/2 的數據包是不按順序發送的,同一個連接裡面連續的數據包,可能屬於不同的回應。因此,必須要對數據包做標記,指出它屬於哪個回應。HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬於哪個數據流。另外還規定,客戶端發出的數據流,ID一律為奇數,伺服器發出的,ID為偶數。數據流發送到一半的時候,客戶端和伺服器都可以發送信號(RST_STREAM幀),取消這個數據流。HTTP/1.1取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。客戶端還可以指定數據流的優先順序。優先順序越高,伺服器就會越早回應。

4. 首部壓縮:HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多欄位都是重複的,,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息壓縮後再發送(SPDY 使用的是通用的DEFLATE 演算法,而 HTTP/2 則使用了專門為首部壓縮而設計的 HPACK 演算法)。;另一方面,客戶端和伺服器同時維護一張頭信息表,所有欄位都會存入這個表,生成一個索引號,以後就不發送同樣欄位了,只發送索引號,這樣就提高速度了。

5. 服務端推送:HTTP/2 允許伺服器未經請求,主動向客戶端發送資源,這叫做伺服器推送(server push)。常見場景是客戶端請求一個網頁,這個網頁裡麪包含很多靜態資源。正常情況下,客戶端必須收到網頁後,解析HTML源碼,發現有靜態資源,再發出靜態資源請求。其實,伺服器可以預期到客戶端請求網頁後,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。

6. HTTPS

HTTPS可以說是安全版的HTTP,HTTPS基於安全SSL/TLS(安全套接層Secure Sockets Layer/安全傳輸層Transport Layer Security)層,即在傳統的HTTP和TCP之間加了一層用於加密解密的SSL/TLS層。HTTP默認使用80埠,HTTPS默認使用443埠。

不使用SSL/TLS的HTTP通信,所有信息明文傳播,會帶來三大風險:

  • 竊聽風險:第三方可以獲取通信內容;
  • 篡改風險:第三方可以修改通信內容;
  • 冒充風險:第三方可以冒充他人進行通信。

SSL/TLS協議是為瞭解決這三大風險而設計的,以期達到:

  • 信息加密傳輸:第三方無法竊聽;
  • 校驗機制:一旦被篡改,通信雙方會立刻發現;
  • 身份證書:防止身份被冒充。

6.1 SSL/TLS發展

  • SSL/1.0:1994年NetScape公司設計,未發布;
  • SSL/2.0:1995年NetScape公司發布,但存在嚴重漏洞;
  • SSL/3.0:1996年NetScape公司發布,得到大規模應用;
  • TLS/1.0:1999年互聯網標準化組織(ISOC)接替NetScape公司,發布SSL的升級版TLS/1.0;
  • TLS/1.1:2006年發布;
  • TLS/1.2:2008年發布;
  • TLS/1.2修訂版:2011年發布。

目前,應用最廣泛的是 TLS/1.0 和 SSL/3.0,且主流瀏覽器已實現 TLS/1.2的支持。

6.2 SSL/TLS運行機制

SSL/TLS的基本思路是公鑰加密法:客戶端先向伺服器索要並驗證公鑰,然後用公鑰加密傳輸來協商生成「對話祕鑰」(非對稱加密),雙方採用「對話祕鑰」進行加密通信(對稱加密)。

通信過程如下:

1. 客戶端發出請求:給出支持的協議版本、支持的加密方法(如RSA公鑰加密)以及一個客戶端生成的隨機數(Client random);

2. 服務端回應:確認雙方通信的協議版本、加密方法,並給出伺服器證書以及一個伺服器生成的隨機數(Server random);

3. 客戶端回應:客戶端確認證書有效,取出證書中的公鑰,然後生成一個新的隨機數(Premaster secret),使用公鑰加密這個隨機數,發送給服務端;

4. 服務端回應:服務端使用自己的私鑰解密客戶端發來的隨機數(Premaster secret),客戶端和服務端根據約定的加密方法,使用三個隨機數,生成「對話祕鑰」;

5. 會話通信:客戶端和服務端使用「對話祕鑰」加密通信,這個過程完全使用普通的HTTP協議,只不過用「會話祕鑰」加密內容。

前四步稱為握手階段,用於客戶端和服務端建立連接和交換參數。整個通信過程可用下圖所示:

6.3 HTTPS特點

  • 緩存:只要在HTTP頭中使用特定命令,就可以緩存HTTPS;
  • 延遲:HTTP耗時 = TCP握手;HTTPS耗時 = TCP握手 + SSL握手。SSL握手耗時大概是TCP握手耗時的三倍左右。

7. 參考鏈接

  1. ruanyifeng.com/blog/201
  2. blog.csdn.net/summy_J/a
  3. jianshu.com/p/52d86558c
  4. ruanyifeng.com/blog/201
  5. ruanyifeng.com/blog/201
  6. blog.cloudflare.com/ann
  7. ruanyifeng.com/blog/201

推薦閱讀:

相關文章