關於HTTP的持久連線特性

2021-08-29 14:32:00 字數 3488 閱讀 5076

http協議是位於傳輸層之上的應用層協議,其網路層基礎通常是tcp協議。tcp協議是面向連線和流的,因此連線的狀態和控制對於http協議而言相當重要。同時,http是基於報文的,因此如何確定報文長度也是協議中比較重要的一點。

persistent connections持久連線

目的 在使用持久連線前,http協議規定為獲取每個url資源都需要使用單獨的乙個tcp連線,這增加了http服務端的負載,引起網際網路擁塞。例如內嵌以及其他類似資料的使用要求乙個客戶端在很短時間內向同乙個服務端發起多個請求。

使用持久連線的優點:

減少tcp連線數量

在乙個連線上實現http請求和應答的流水,即允許客戶端發出多個請求,而不必在接收到前一請求的應答後才發出下一請求,極大減少時間消耗

後續請求延遲減少,無需再在tcp握手上耗時

可以更加優雅地實現http協議,由於持續連線的存在無需報告錯誤後無需關閉連線,因此客戶端可使用最新的協議特性發出請求,如果接收到表示錯誤的應答,則換用更舊的語義。

總體描述

http/1.1和之前版本的顯著區別是http/1.1預設使用持久連線。即,除非服務端在應答中明確指出,客戶端應當假定服務端會維持乙個持久連線,即使從服務端收到的應答是報告錯誤。

持久連線對關閉tcp連線的行為提供訊號量機制支援。這個訊號量是在http頭中的connection域設定,注意client向proxy發出請求時該域可能被proxy-connection域替換。一旦close訊號被表明,客戶端絕不能再通過該連線傳送更多的請求。

協商(negotiation)

http/1.1 服務端可以假定http/1.1客戶端會維持持久連線,除非請求中connection域的值是"close".同樣的,如果服務端打算在送出應答後立即關閉連線,它應當在應答中包含同樣的connection域。(tcp連線關閉是雙向的,此時tcp進入半關閉狀態)

同樣的,http/1.1客戶端可以期望連線是持久的,除非如前所述收到表示連線關閉的應答。當然,也可以主動發出乙個包含connection:close的請求以表明終止連線。

無論客戶端還是服務端發出的報文包含connection:close,則該請求均為連線上的最後乙個請求(服務端發出此應答後關閉,因此不可能接收更多的請求)

報文傳輸長度

為保證永續性,連線上的報文都必須有乙個自定義的報文傳輸長度(否則必須通過連線的關閉表示報文結束,因為tcp連線是面向流的),確定的規則按優先順序由高到低排列如下:

報文傳輸長度指報文中出現的報文體的長度(即,不包括頭長度,因為報文頭的結束可通過連續兩個crlf確定)

1.任何絕不能包含報文體(如1xx,204,304)的應答訊息總是以頭域後的第乙個空行結束,無視頭中所有的entity型別域的設定,包括content-length域。

2.transfer-encoding域出現,其值為除"identify"以外的其他值,則用"chunked"傳輸編碼方式確定傳輸長度,具體方式留待下篇分析。

3.content -length域出現,且transfer-encoding域未出現(出現則忽略content-length域)。content-length域的值為十進位制數的位元組序,如content-length:1234,則1、2、3、4是分別作為乙個octet傳輸的,因此需要atoi轉換成數值。

4.如果報文使用了"multipart/byteranges"的**型別,且沒對傳輸長度做前面的指明,則這種自分割的**型別定義了傳輸長度。具體參見range頭域的說明。

5.服務端關閉連線(此方法不可用於客戶端發出的請求報文,因為客戶端關閉連線則使得服務端無法傳送應答).

為保持和http/1.0的相容性, 包含報文體的http/1.1請求必須包含合法的content-length頭域,除非明確知道服務端是http/1.1相容的.如果請求包含訊息體, 而沒有content-length域,那麼如果服務端無法確定訊息長度時,它會返回400(無效請求),或者堅持獲取合法content-length 而返回411(要求包含長度).

所有接收實體的http/1.1應用程式必須接受"chunked"傳輸編碼, 這樣允許當報文長度無法預先確定時可以運用此機制獲取報文長度.

報文不能同時包含content-length頭域和非"identity" transfer-encoding.如果出現了, content-length域必須被忽略.

當content-length域在允許報文體的報文中存在時, 其域值必須嚴格等於訊息體中的8位元位元組.http/1.1 user agent 必須在接收並檢測到乙個錯誤的長度時提醒使用者.

以上方法中,最常見的還是使用content-length域表示報文體長度,transfer-encoding需要按格式解碼才能還原出發送編碼前的報文。

流水 支援持久連線的客戶端可以流水傳送請求,服務端必須按傳送的順序傳送應答。

假定持久連線和連線後即可流水的客戶端應當做好在第一次流水失敗後重新嘗試此連線。在這樣的嘗試中,在確定連線是持久的之前,客戶端不能再流水。

客戶端同樣必須準備好在服務端送回所有相關應答前就關閉連線時重發請求。

不應流水non-idempotent方法

proxy servers

對於**服務端而言,正確實現connection頭域指定的屬性尤為重要。

**服務端必須分立通告它的客戶端和連線的原始服務端持久連線的屬性,每個持久連線設定僅針對乙個傳輸連線。

實踐考量

超時值,服務端通常會為每個連線維護乙個定時器,一旦某個連線不活躍超過一定時間值,服務端會關閉此連線。考慮到乙個客戶端可能通過**服務端發出更多連線,**服務端通常會將超時值設定得更高。

還有一些關於從非同步關閉中恢復的討論。

報文傳輸要求

使用tcp流控制來解決服務端臨時負載過高問題,而不是簡單的依賴客戶端重連而關閉連線。

監視連線情況以獲取錯誤狀態訊息

關於使用100(繼續)狀態碼

100狀態碼用於客戶端傳送請求體之前測試是否可以傳送該請求,對於proxy,有以下要求:

1.如果**服務端接收到包含expect頭域值為"100-continue"的請求, 而不明確知道下一跳服務不支援http/1.1以上版本, 則它必須**這個請求, 包括expect頭域.

2.如果**知道下一跳服務端為http/1.0或者更低版本, 則它不能**此請求, 且必須以407應答客戶端.

3.如果明確知道發出請求的客戶端版本為http/1.0或者更低,則**服務端絕不能**100應答,這條規則凌駕於**1xx應答的一般準則.

connection頭域說明

bnf文法:

connection = "connection" ":" 1#(connection-token)

connection-token = token

connection頭域中的token用於指定對於特定連線有意義的選項,因此proxy在**前要掃瞄此域,從頭中去除和token同名的域。例如connection:range,則要去掉range域。

http/1.1定義了close這個token,傳送者用此token表示在完成這個報文所屬請求/應答的收發後連線將關閉。

HTTP之持久連線

http 1.1 允許 http 裝置在事務處理結束之後將 tcp 連線保持在開啟狀態,以便為未來的 http 請求重用現存的連線。在事務處理結束後仍然保持在開啟狀態的 tcp 連線被稱為持久連線。非持久連線會在每個事務結束之後關閉。持久連線會在不同事務之間保持開啟狀態,直到客戶端或伺服器決定將其關...

HTTP協議詳解 持久連線與非持久連線

最近寫作完http協議一節,略做總結 非持久連線是在http 1.0中定義,而對於http 1.1中預設的是持久連線 帶流水線 以下是詳細描述 非持久連線 的概念 某網頁由最基本的 html 和10個jpeg 影象構成,10個jpeg 影象檔案存放在同一臺伺服器中。設這個網頁的url為www.ser...

Http的持久連線(Keep Alive模式)

關於持久連線 http 1.1允許http裝置在事務處理結束之後將tcp連線保持在開啟狀態,以便為未來的http請求重用現存的連線。在事務處理結束之後仍然保持在開啟狀態的tcp連線被稱為持久連線。持久連線會在不同事務之間保持開啟狀態,直到客戶端或伺服器決定將其關閉為止。優點 重用已對目標伺服器開啟的...