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框架