HTTP2協(xié)議
HTTP的1.1的現(xiàn)狀:
http1.1過于龐大,有很多實(shí)現(xiàn)的細(xì)枝末節(jié)很難徹底實(shí)現(xiàn)。導(dǎo)致客戶端和服務(wù)端的互用性存在問題。
http 1.1很難榨干TCP協(xié)議所能提供的所有性能。
http1.1對(duì)網(wǎng)絡(luò)延遲非常敏感,原因是HTTP pipelining還存在很多問題。
http1.1存在線頭阻塞,雖然利用HTTP pipelinling技術(shù)可以把多個(gè)http請(qǐng)求放到一個(gè)TCP連接中一一發(fā)送,但是客戶端還是需要按照發(fā)送順序來接收響應(yīng)。如果前一個(gè)請(qǐng)求非常耗時(shí),那么后續(xù)請(qǐng)求都會(huì)受到影響,這就是所謂的線頭阻塞。
曾經(jīng)為了克服延遲的操作
Spriting
將小圖合并成大圖,再用前端技術(shù)進(jìn)行切割。但是不利于緩存,當(dāng)其中一張圖片發(fā)生變化的時(shí)候,整張大圖都要改變。
Inlining
通過內(nèi)聯(lián),把圖片數(shù)據(jù)直接放到css文件中。
Concatenation
通過拼接,將多個(gè)文件合并成一個(gè)文件。
Sharding
分片將服務(wù)分散在多個(gè)服務(wù)器上,來讓客戶端同時(shí)和多個(gè)主機(jī)建立多條鏈接,來提高效率。
http2
http2的前身是SPDY。
基于TLS之上的http2協(xié)商
有兩個(gè)協(xié)商協(xié)議:SPDY使用NPN,HTTP2使用ALPN。他們兩個(gè)的主要區(qū)別在于誰來決定通訊協(xié)議,ALPN由服務(wù)端選擇,NPN又客戶端選擇?;赥LS時(shí),可以不使用Upgrade來升級(jí),而使用TLS的一個(gè)擴(kuò)展來協(xié)商。
基于非TLS的http2
會(huì)先用一次通訊,客戶端給服務(wù)端發(fā)送升級(jí)請(qǐng)求,服務(wù)端如果支持會(huì)返回“101 Switching”作為回復(fù),則升級(jí)成http2,但是現(xiàn)在還沒有任何主流瀏覽器支持非TLS的http2。
二進(jìn)制的http2協(xié)議
HTTP2是一個(gè)二進(jìn)制協(xié)議。
HTTP1.1是一個(gè)基于文本的協(xié)議,但是要針對(duì)開始和結(jié)束識(shí)別起來相當(dāng)復(fù)雜,而壓縮以及tls加密也降低了基于純文本實(shí)現(xiàn)的價(jià)值。
多路復(fù)用的流
每個(gè)單獨(dú)的HTTP2鏈接都可以包含多個(gè)并發(fā)的流,既然如此,那么會(huì)導(dǎo)致各個(gè)流的數(shù)據(jù)包會(huì)被混合在一起,到那時(shí)在終點(diǎn)處,會(huì)根據(jù)Stream Identifier重新組裝,從而得到完整的數(shù)據(jù)。
優(yōu)先級(jí)和依賴性
每個(gè)流都包含一個(gè)優(yōu)先級(jí),當(dāng)資源有限的時(shí)候,服務(wù)端會(huì)根據(jù)優(yōu)先級(jí)選擇發(fā)送哪些流。
優(yōu)先級(jí)和依賴關(guān)系可以在傳輸過程中被動(dòng)態(tài)的改變。這樣當(dāng)用戶在滾動(dòng)一個(gè)全是圖片的頁面的時(shí)候,瀏覽器就能指定哪些圖片擁有更高的優(yōu)先級(jí)?;蛘咴谀闱袚Q便簽頁的時(shí)候,瀏覽器可以提升新切換到頁面所包含流的優(yōu)先級(jí)。
頭壓縮
http的頭變得越來越大,但是存在大量一致的東西,這些東西值得被壓縮。用的壓縮算法是HPACK,更加安全。
重置
增加重置Content-Length的方法,通過RST_STREAM幀,而不是需要重新建立TCP請(qǐng)求。
服務(wù)器推送
當(dāng)客戶端需要資源X的時(shí)候,服務(wù)器知道它肯定還需要資源Y,就把Y也推送給客戶端,這樣客戶端在想要Y資源的時(shí)候,會(huì)直接從緩存拿取。
流量控制
對(duì)于每個(gè)流來說,兩端都必須告訴對(duì)方自己還有足夠的空間來處理新的數(shù)據(jù),而在該窗口被擴(kuò)大前,另一端只能發(fā)這么多。
HTTP2協(xié)議詳細(xì)內(nèi)容
- http/2通過定義一個(gè)優(yōu)化的HTTP語義到底層鏈接的映射來解決一條連接只能一次請(qǐng)求,并可以高效地使用HTTP報(bào)頭,還允許請(qǐng)求具有優(yōu)先級(jí),讓更重要的請(qǐng)求更快地完成,進(jìn)一步提高了性能。
- http2支持http1.1的所有核心功能(持久連接,在響應(yīng)后不關(guān)閉TCP通道,新增首部字段Host,客戶端指名要訪問的主機(jī),使得服務(wù)端可以在統(tǒng)一域名的不同主機(jī)之間實(shí)現(xiàn)多個(gè)虛擬web站點(diǎn),新增http pipelining,允許(GET,HEAD)同時(shí)發(fā)送等)
- http2中基礎(chǔ)的協(xié)議單元是幀,每個(gè)不同類型的幀都服務(wù)于不同的目的。比如HEADERS和DATA幀構(gòu)成了基本的HTTP請(qǐng)求和應(yīng)答。
- 請(qǐng)求的多路復(fù)用即在每個(gè)HTTP請(qǐng)求/應(yīng)答在各自的流中完成數(shù)據(jù)交換,由于每個(gè)流之間都是相互獨(dú)立的,因此即使請(qǐng)求和應(yīng)答被阻塞或者速度很慢都不會(huì)影響各自流中的處理流程。
- 在請(qǐng)求者請(qǐng)求url之前,需要先確定上游服務(wù)器是否支持HTTP2
- http的版本協(xié)議有兩種標(biāo)識(shí)符:h2代表建立在TLS上的HTTP2通訊,h2c代表不適用TLS協(xié)議。存在Upgrade。
所有的幀都以一個(gè)9字節(jié)的報(bào)頭開始, 后接變長的載荷:
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
-
Length: 載荷的長度, 無符號(hào)24位整型. 對(duì)于發(fā)送值大于2^14 (長度大于16384字節(jié))的載荷, 只有在接收方設(shè)置SETTINGS_MAX_FRAME_SIZE為更大的值時(shí)才被允許注: 幀的報(bào)頭9字節(jié)不算在length里.
Type: 8位的值表示幀類型, 決定了幀的格式和語義. 協(xié)議實(shí)現(xiàn)上必須忽略任何未知類型的幀.Flags: 為Type保留的bool標(biāo)識(shí), 大小是8位. 對(duì)確定的幀類型賦予特定的語義, 否則發(fā)送時(shí)必須忽略(設(shè)置為0x0).R: 1位的保留字段, 尚未定義語義. 發(fā)送和接收必須忽略(0x0).Stream Identifier: 31位無符號(hào)整型的流標(biāo)示符. 其中0x0作為保留值, 表示與連接相關(guān)的frames作為一個(gè)整體而不是一個(gè)單獨(dú)的流.
stream標(biāo)識(shí)符:客戶端使用奇數(shù),服務(wù)端使用偶數(shù)。