一些HTTP2筆記

HTTP 1.1發明以來發生了哪些變化

1.從幾KB大小的消息,到幾MB大小的消息

2.每個頁面小於10個資源,到每頁面100多個資源

3.從文本爲主的內容,到富媒體(如圖片,聲音,視頻)爲主的內容

4.對頁面內容實時性高要求的應用越倆越多

 

HTTP 1.1的高延遲問題

高延遲帶來頁面加載速度的降低

1.隨着帶寬的增加,延遲並沒有顯著下降

2.併發連接有限

3.同一連接同時只能在完成一個HTTP事務(請求/響應)才能處理下一個事務

 

高延遲VS高帶寬

單連接上的串行請求

無狀態導致的高傳輸量(低網絡效率)

無狀態特性帶來的巨大HTTP頭部

重複傳輸的體積巨大的http頭部

特別是cookie

HTTP 1.1爲了解決性能問題做過的努力

1.Spriting 合併多張小圖爲一張大圖供瀏覽器JS切割使用

缺點:不能區別對待,一張小圖的更改,整個大圖需要重新傳輸

2.Inlining內聯:將圖片嵌入到CSS或者HTML文件中,減少網絡請求次數

3.Concatenation拼接:將多個體積較小的js使用webpack等工具打包成1個體積更大的js文件

缺點:1個文件的改動導致用戶重新下載多個文件

4.Sharding分片:將同一頁面的資源分散到不同域名下,提升連接上限

 

HTTP 1.1不支持服務器推送消息

 

HTTP2 特性

SPDY(2012-2016 google)

HTTP2 (RFC7540 2015.5)

1.在應用層上修改,基於並充分挖掘TCP協議性能

2.客戶端向server發送request這種基本模型不會變

3.老的scheme不會變,沒有http2://

4.使用http 1.x的客戶端和服務器可以無縫的通過代理方式轉接到http 2.x上

5.不識別http 2的代理服務器可以將請求降級到http1.x

主要特性

傳輸數據量的大幅減少

1.以二進制方式傳輸

2.標頭壓縮

多路複用及相關功能

消息優先級

服務器的消息推送

 

HTTP2是不是必須基於TLS/SSL協議

1.IETF標準不要求必須基於TLS/SSL協議

2.瀏覽器要求必須基於TLS/SSL協議

(1).希望網絡安全

(2).利用現有的TLS握手

3.在TLS層ALPN擴展做協商,只認HTTP 1.x的代理服務器不會干擾HTTP 2

4.schema: http://和https://默認基於80和443端口

5.h2:基於TLS協議運行的http 2被稱爲h2

6.h2c:直接在tcp協議之上運行的http 2被稱爲h2c

 

h2與h2c的區別

h2c:不使用TLS協議進行協議升級

客戶端測試工具:curl (7.46.0版本及以上支持http 2)

curl http://nghttp/2.org -http/2 -v 

然後客戶端還需要發送Magic幀

Preface(ASCII編碼,12字節)

1.何時發送

接收到服務器發送來的101 Switching Protocols

TLS握手成功後

2.Preface內容

3.發送完畢後,應緊跟SETTING幀

h2:使用TLS協議進行協議升級

TLS通訊過程

1.驗證身份

2.達成安全套件共識

3.傳遞密匙

4.加密通訊

NPN:(Next Protocol Negotiation)

SPDY使用的由客戶端選擇協議的NPN擴展

ALPN

在上面的做了改進,由客戶端告訴支持哪些協議,服務器做一個選擇

 

HTTP 2核心概念

1.連接Connection:1個TCP連接,包含一個或者多個stream

2.數據流stream:一個雙向通訊數據流,包含一個或者多條Message

3.消息Message:對應HTTP 1中的請求或者響應,包含一條或者多條Frame

4.數據幀Frame:最小單位,以二進制壓縮格式存放HTTP 1中的內容

Stream,Message,Frame間的關係

每一個stream都會有一個id標識,多個幀之間通過這個stream id對應起來

frame與message沒有概念關聯起來

消息的組成:Headers幀與Data幀

在wireshare中,每一個報文都是一個frame幀

傳輸中無序,接收時組裝

不同的stream之間可以無序,但是同一個stream之間得是有序的

 

消息與幀

http 1.x中的一個請求或者響應就是一個message消息

http 2 中上圖是一個幀, 是通過業務上的邏輯關係,一個stream中可以存在多個message,而一個message通過多個幀組成

幀格式:Steam ID的作用

實現多路複用的關鍵

1.接收端的實現可據此併發組裝消息:

所以同一個id的不能無序,多個id的才能利用多路複用,

同一個id裏面的多個frame是無法利用多路複用的。

要實現併發要新起一個stream

2.同一Stream內的frame必須是有序的(無法併發)

3.SETTINGS_MAX_CONCURRENT_STREAMS控制着併發stream數

推送依賴性請求的關鍵

1.由客戶端建立的流必須是奇數

2.由服務器建立的流必須是偶數(一般是推送)

流狀態管理的約束性規定

1.新建立的流ID必須大於曾經建立過的狀態爲opened或者reserved的流ID

2.在新建立的流上發送幀時,意味着將更小ID且爲idle狀態的流置位closed狀態

3.Stream ID不能複用,長連接耗盡ID應創建新連接

應用層流控僅影響數據幀

1.stream ID爲0的流僅用於傳輸控制幀

2.在HTTP 1升級到h2c中,以ID爲1流返回響應,之後流進入half-closed(local)狀態

 

幀格式

9字節標準幀頭部:幀長度

1.0至2^14(16384) - 1

所有實現必須可以支持16KB以下的幀

2.2^14 至 2^24 - 1(16777215)

傳遞16KB到16MB的幀時,必須接受端首選公佈自己可以處理此大小

通過SETTINGS_MAX_FRAME_SIZE幀(Identifier=5)告知

幀類型Type

Setting設置幀格式(type=0x4)

1,設置幀並不是協商,而是發送方向接收方通知其特性、能力

2.一個設置幀可同時設置多個對象

Identifier:設置對象

Value:設置值

Setting設置對象的類型

hpack壓縮算法 

1.靜態字典

2.動態字典

3.哈夫曼編碼

第一次傳輸是完成的key-value,第二次傳輸的時候,發現只有path變了,其他的key-value都可以用索引表裏面的數字來代替,

如下圖

HPACK壓縮比:h2load

節省空間61.94%

huffman編碼

1.原理:出現概率較大的符號採用較短的編碼,概率較小的符號採用較長的編碼

2.靜態huffman編碼

 

3.動態huffman編碼

 

服務端推送

提前將資源推送至瀏覽器緩存

特性:推送可以基於已發送的請求,例如客戶端請求html,主動推送js文件

實現方式:1.推送資源必須對應一個請求 2.請求由服務端PUSH_PROMISE幀發送 3.響應在偶數ID的STREAM中發送

http1.1中獲取html後,需要css資源時

瀏覽器觸發:需要兩次往返

PUSH_PROMISE方式

1.在stream1中通知客戶端CSS資源即將來臨

2.在stream2中發送css資源(stream1和stream2可以併發)

複雜點的例子

PUSH幀的格式

PUSH_PROMISE幀, type=0x5 只能由服務器發送

PUSH推送模式的禁用

SETTINGS_ENABLE_PUSH(0x2)

1表示啓用推送功能

0表示禁用推送功能

 

stream流狀態變遷

stream特性:

1.一條tcp連接上,可以併發存在多個處於Open狀態的stream

2.客戶端或者服務器都可以創建新的stream

3.客戶端或者服務器都可以首先關閉stream

4.同一條stream內的frame幀 是有序的

5.從stream ID的值可以輕易分辨PUSH消息

所有爲發送header/data 消息而創建的流,從1,3,5等遞增奇數開始

所有爲發送PUSH消息而創建的流,從2,4,6等遞增偶數開始

Message特性:

1.一條http message由1個header(可能含有0個或者多個持續幀構成)及0個或者多個DATA幀構成

2.header消息同時包含http 1.1中的start line與headers部分

3.取消http 1.1中的不定長chunk消息

Get消息發送示例

Post消息發送示例

stream流的狀態

1.幀符號

   H:headers幀

   PP:PUSH_PROMISE幀

   ES:END_STREAM標誌位

   R:RST_STREAM幀

2.流狀態      

idle:起始狀態

closed

open:可以發送任何幀

half closed :單向關閉

   remote:不再接收數據幀

   local:不能再發送數據幀

reserved:

remote

local

RST_STREAM幀(type=0x3)

http2多個流共享同一個連接,RST幀允許立刻終止一個未完成的流

RST_STREAM幀不使用任何flag

RST_STREAM幀的格式

常見錯誤碼

Stream優先級與資源分配規則

Priority優先級設置幀

1.幀類型 type=0x2

2.不使用flag標誌位字段

3.Stream Dependency:依賴流

4.Weight權重:取值範圍1-256,默認權重16

5.僅針對stream流,若id爲0試圖影響連接,則接收端必須報錯

6.在idle和closed狀態下,仍然可以發送Priority幀

數據流優先級

12+4 = 16  12/16 4/16   分配內存,buffer

只有D完成後,才能去做C,這時候的D和C優先級沒有用

這種A和B的優先級纔有用

E和C ,A和B

exclusive標誌位

E爲0

B和C依賴A, E爲0時,D依賴A

E爲1

B和C依賴A,E爲1時,D獨佔,D依賴A,B和C依賴D

http2 流量控制

http 1.1由tcp層進行流量控制

前提:http1的tcp連接上沒有多路複用、

http2需要應用層控制

 問題:

1.多stream爭奪tcp的流控制,互相干擾可能造成stream阻塞

2.代理服務器內存有限,上下游網速不一致時,通過流控管理內存

http2中的流控制既針對單個stream,也針對整個tcp連接

1.客戶端與服務器都具備流量控制能力

2.單向流控制:發送和接收獨立設定流量控制

3.以信用爲基礎:接收端設定上限,發送端應當遵循接收端發出的指令。

4.流量控制窗口(流或者連接)的初始值是65535字節

5.只有DATA幀服從流量控制

6.流量控制不能被禁用

window_update幀

1.type=0x8,不使用任何flag

2.窗口範圍是1- 2^31 -1 (2147483647)字節

 0是錯誤的,接收端應該返回PROTOCOL_ERROR

3.當stream ID爲0時表示對連接流控,否則爲對stream流控

4.流控僅針對直接建立tcp連接的兩端

  代理服務器並不需要透傳window_update幀

  接收端的縮小流控窗口會最終傳遞到源發送端

流控制窗口

1.窗口大小由接收端告知

2.窗口隨着DATA幀的發送而減少

SETTINGS_MAX_CONCURRENT_STREAMS併發流

1.併發僅統計open或者half-close狀態的流(不包含用於推送和的reserved狀態)

2.超出限制後的錯誤碼

PROTOCOL_ERROR

REFUSED_STREAM

http2與gRPC框架

 

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