天天看點

你了解HTTP長連接配接嗎?

長連接配接出現的前夜

在了解長連接配接之前,我們先看看與之對應的短連接配接是什麼?在HTTP協定的初始版本中,每進行一次HTTP通信就要斷開一次TCP連接配接。

早前的通信情況來看,因為都是些容量很小的文本傳輸,是以沒有太大的問題,但是随着HTTP傳輸文檔中包含大量的富文本,比如使用浏覽器浏覽一個包含多張圖檔的HTML頁面的時候,在發送請求通路HTML頁面資源的同時,也會請求該HTML頁面包含的其他資源,是以,每次的請求都會造成無謂的TCP連接配接的建立和斷開,增大了開銷。

keep-alive字段

為了解決上面的問題,有些浏覽器在請求的時候,使用了一個非标準的Connection字段。
Connection: keep-alive           
上面的字段要求伺服器不要關閉TCP連接配接,以便其他請求複用。伺服器同樣回應這個字段。
Connection: keep-alive           
這樣一個可以複用的TCP連接配接就建立了,直到用戶端或伺服器主動關閉連接配接,但是這不是标準的字段,不同實作的行為可能不一緻,是以不是根本的解決辦法。

長連接配接出現了

1997年1月,HTTP/1.1版本釋出了,它進一步完善了HTTP協定,直到現在還是最流行的版本。

HTTP/1.1版的最大變化就是引入了持久連接配接(HTTP Persistent Connections),即TCP預設連接配接不關閉,可以被多個請求複用,不用聲明keep-alive字段。

持久連接配接的好處

  • 減少了TCP連接配接的重複建立和斷開造成的額外開銷,減輕了伺服器端的負載。
  • 使得HTTP請求和響應能夠更早的結束,這樣web頁面的顯示速度也就對應的提高了。
用戶端和伺服器端發現對方一段時間内沒有活動,就可以主動關閉連接配接。不過規範的做法是,用戶端在最後一個請求時,發送Connection: close,明确要求伺服器關閉TCP連接配接。
Connection: close           
目前,對同一個域名,大多數浏覽器允許同時建立6個持久連接配接。

管道機制

注意:管道機制是基于持久連接配接的

HTTP/1.1版還引入了管道機制,即在同一個TCP連接配接裡面,用戶端可以同時發送多個請求,這樣就進一步改進了HTTP協定的效率,以前發送請求後需要等待并接收響應,才能發送下一個請求。管線化技術出現後,不用等待響應即可直接發送下一個請求,這樣就能夠做到同時并行發送多個請求,而不需要一個接一個的等待響應了,與挨個連接配接相比,用持久連接配接可以讓請求更快結束。而管線化技術則比持久連接配接要快的多,請求數越多,時間差就越明顯。

案例

假如一個用戶端需要請求兩個資源,以前的做法是,在同一個TCP連接配接裡面,先發送A請求,然後等待伺服器做出相應,收到後再發出B請求,管道機制則是允許浏覽器同時發出A請求和B請求,但是伺服器還是按照順序,先回應A請求再回應B請求。

Content-Length字段

一個TCP連接配接可以傳回多個響應,勢必就要有一種機制,區分資料包是屬于哪一個響應的,這就是Content-Length字段的作用,聲明本次回應的資料長度。
Content-Length: 3495           
上面的代碼告訴浏覽器,本次響應的長度是3495個位元組,後面的位元組就屬于下一個回應了。在1.0版本中,Content-Length字段不是必須的,因為浏覽器發現伺服器關閉了TCP連接配接,就表明收到的資料包已經全了。

分塊傳輸編碼

使用Content-Length字段的前提條件是,伺服器發送響應之前,必須知道響應的資料長度,對于一些很耗時的動态操作來說,這意味着,伺服器要等到所有操作完成,才能發送資料,這樣的效率不行,更好的處理方法是,産生一塊資料,就發送一塊,采用流模式代替緩存模式。

是以,1.1版本規定可以不使用Content-Length字段,而是使用分塊傳輸編碼,隻要請求或響應的頭資訊中有Transfer-Encoding字段,就表明回應将由數量未定的資料塊組成。

Transfer-Encoding: chunked           
每個非空的資料塊之前,會有一個16進制的數值,表示這個塊的長度,最後是一個大小為0的塊,就表示本次回應的資料發送完了。

長連接配接帶來的問題

雖然HTTP1.1版本允許複用TCP連接配接,但是同一個TCP連接配接裡面,所有的資料通信是按照次序進行的,是以伺服器隻有處理完一個響應,才會進行下一個響應,如果前面的響應特别慢,後面就會有許多請求排隊等待着,這就稱之為隊頭阻塞。

如何避免?

  1. 減少請求數。
  2. 同時多開持久連接配接。

繼續閱讀