HTTP/3發(fā)布了,我們來談?wù)凥TTP/3
經(jīng)過了多年的努力,在 6 月 6 號,IETF (互聯(lián)網(wǎng)工程任務(wù)小組) 正式發(fā)布了 HTTP/3 的 RFC, 這是超文本傳輸協(xié)議(HTTP)的第三個(gè)主要版本,完整的 RFC 超過了 20000 字,非常詳細(xì)的解釋了 HTTP/3。

HTTP 歷史

1991 HTTP/1.1 2009 Google 設(shè)計(jì)了基于TCP的SPDY 2013 QUIC 2015 HTTP/2 2018 HTTP/3

QUIC 協(xié)議概覽


HTTP over QUIC即HTTP/3的含義HTTP/3, QUIC是繞不過去的, 下面是幾個(gè)重要的QUIC特性.0 RTT建立連接
RTT: round-trip time, 僅包括請求訪問來回的時(shí)間

HTTP/2的連接建立需要3 RTT, 如果考慮會話復(fù)用, 即把第一次握手計(jì)算出來的對稱密鑰緩存起來, 那也需要2 RTT. 更進(jìn)一步的, 如果TLS升級到1.3, 那么HTTP/2連接需要2RTT, 考慮會話復(fù)用需要1RTT. 如果HTTP/2不急于HTTPS, 則可以簡化, 但實(shí)際上幾乎所有瀏覽器的設(shè)計(jì)都要求HTTP/2需要基于HTTPS.HTTP/3首次連接只需要1RTT, 后面的鏈接只需要0RTT, 意味著客戶端發(fā)送給服務(wù)端的第一個(gè)包就帶有請求數(shù)據(jù), 其主要連接過程如下:首次連接, 客戶端發(fā)送 Inchoate Client Hello, 用于請求連接;服務(wù)端生成g, p, a, 根據(jù)g, p, a算出A, 然后將g, p, A放到Server Config中在發(fā)送 Rejection消息給客戶端.客戶端接收到g,p,A后, 自己再生成b, 根據(jù)g,p,a算出B, 根據(jù)A,p,b算出初始密鑰K, B和K算好后, 客戶端會用K加密HTTP數(shù)據(jù), 連同B一起發(fā)送給服務(wù)端. 服務(wù)端接收到B后, 根據(jù)a,p,B生成與客戶端同樣的密鑰, 再用這密鑰解密收到的HTTP數(shù)據(jù). 為了進(jìn)一步的安全(前向安全性), 服務(wù)端會更新自己的隨機(jī)數(shù)a和公鑰, 在生成新的密鑰S, 然后把公鑰通過 Server Hello發(fā)送給客戶端. 連同Server Hello消息, 還有HTTP返回?cái)?shù)據(jù).

連接遷移
Connection ID, 即使IP或者端口發(fā)生變化, 只要Connection ID沒有變化, 那么連接依然可以維持.隊(duì)頭阻塞/多路復(fù)用
HTTP/1.1和HTTP/2都存在隊(duì)頭阻塞的問題(Head Of Line blocking).ACK消息, 以確認(rèn)對象已接受數(shù)據(jù). 如果每次請求都要在收到上次請求的ACK消息后再請求, 那么效率無疑很低. 后來HTTP/1.1提出了Pipeline技術(shù), 允許一個(gè)TCP連接同時(shí)發(fā)送多個(gè)請求. 這樣就提升了傳輸效率.
Frame通過一條TCP連接同時(shí)被傳輸, 這樣即使一個(gè)請求被阻塞, 也不會影響其他的請求.
但是, HTTP/2雖然可以解決請求這一粒度下的阻塞, 但HTTP/2的基礎(chǔ)TCP協(xié)議本身卻也存在隊(duì)頭阻塞的問題. HTTP/2的每個(gè)請求都會被拆分成多個(gè)Frame, 不同請求的Frame組合成Stream, Stream是TCP上的邏輯傳輸單元, 這樣HTTP/2就達(dá)到了一條連接同時(shí)發(fā)送多個(gè)請求的目標(biāo), 其中Stram1已經(jīng)正確送達(dá), Stram2中的第三個(gè)Frame丟失, TCP處理數(shù)據(jù)是有嚴(yán)格的前后順序, 先發(fā)送的Frame要先被處理, 這樣就會要求發(fā)送方重新發(fā)送第三個(gè)Frame, Steam3和Steam4雖然已到達(dá)但卻不能被處理, 那么這時(shí)整條鏈路都會被阻塞.


QUIC的傳輸單位是Packet, 加密單元也是Packet, 整個(gè)加密, 傳輸, 解密都基于Packet, 這就能避免TLS的阻塞問題. QUIC基于UDP, UDP的數(shù)據(jù)包在接收端沒有處理順序, 即使中間丟失一個(gè)包, 也不會阻塞整條連接. 其他的資源會被正常處理.
擁塞控制
慢啟動: 發(fā)送方像接收方發(fā)送一個(gè)單位的數(shù)據(jù), 收到確認(rèn)后發(fā)送2個(gè)單位, 然后是4個(gè), 8個(gè)依次指數(shù)增長, 這個(gè)過程中不斷試探網(wǎng)絡(luò)的擁塞程度. 避免擁塞: 指數(shù)增長到某個(gè)限制之后, 指數(shù)增長變?yōu)榫€性增長 快速重傳: 發(fā)送方每一次發(fā)送都會設(shè)置一個(gè)超時(shí)計(jì)時(shí)器, 超時(shí)后認(rèn)為丟失, 需要重發(fā) 快速恢復(fù): 在上面快速重傳的基礎(chǔ)上, 發(fā)送方重新發(fā)送數(shù)據(jù)時(shí), 也會啟動一個(gè)超時(shí)定時(shí)器, 如果收到確認(rèn)消息則進(jìn)入擁塞避免階段, 如果仍然超時(shí), 則回到慢啟動階段.
1. 熱插拔
2. 前向糾錯(cuò) FEC

3. 單調(diào)遞增的Packer Number
Sequence Number和ACK來確認(rèn)消息是否有序到達(dá), 但這樣的設(shè)計(jì)存在缺陷.RTT: Round Trip Time, 往返事件 RTO: Retransmission Timeout, 超時(shí)重傳時(shí)間

Sequence Number不同, Packet Number嚴(yán)格單調(diào)遞增, 如果Packet N丟失了, 那么重傳時(shí)Packet的標(biāo)識就不會是N, 而是比N大的數(shù)字, 比如N+M, 這樣發(fā)送方接收到確認(rèn)消息時(shí), 就能方便的知道ACK對應(yīng)的原始請求還是重傳請求.4. ACK Delay

5. 更多的ACK塊
ACK, 而QUIC最多可以捎帶256個(gè)ACK block, 在丟包率比較嚴(yán)重的網(wǎng)絡(luò)下, 更多的ACK可以減少重傳量, 提升網(wǎng)絡(luò)效率.瀏覽控制
Stream, 好比有一條道路, 量都分別有一個(gè)倉庫, 道路中有很多車輛運(yùn)送物資. QUIC的流量控制有兩個(gè)級別: 連接級別(Connection Level)和Stream 級別(Stream Level).
(flow control receivce offset - consumed bytes) < (max receive window/2)時(shí), 接收方會發(fā)送WINDOW_UPDATE frame告訴發(fā)送方你可以再多發(fā)送數(shù)據(jù), 這時(shí)候flow control receive offset就會偏移, 接收窗口增大, 發(fā)送方可以發(fā)送更多數(shù)據(jù)到接收方.
Stream級別對防止接收端接收過多數(shù)據(jù)作用有限, 更需要借助Connection級別的流量控制. 理解了Stream流量那么也很好理解Connection的流控. Stream中,
接收窗口=最大接受窗口 - 已接收數(shù)據(jù)而對于Connection來說:接收窗口 = Stream1 接收窗口 + Stream2 接收窗口 + ... + StreamN 接收窗口參考鏈接
HTTP/3 原理實(shí)戰(zhàn) (https://mp.weixin.qq.com/s?__biz=MjM5ODYwMjI2MA==&mid=2649746858&idx=1&sn=26e90bb6dde7541fb9fe9f121eb11984&scene=21#wechat_redirect)
作者:shuerbuzuo
來源:http://know.shuerbuzuo.cn/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/HTTP3.html#%E6%B5%8F%E8%A7%88%E6%8E%A7%E5%88%B6
版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),僅供分享學(xué)習(xí),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會立即刪除并表示歉意。謝謝!
END
推薦閱讀
END
一鍵生成Springboot & Vue項(xiàng)目!【畢設(shè)神器】
Java可視化編程工具系列(一)
Java可視化編程工具系列(二)
順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,
GitHub地址:https://github.com/javadevbooks/books
電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..

順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,
GitHub地址:https://github.com/javadevbooks/books
電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..
