成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐總結(jié)

移動(dòng)開發(fā)
在 HTTP/0.9 和 HTTP/1.0 中,第3步之后,服務(wù)端就會(huì)關(guān)閉連接,也就是TCP的四次揮手,但是在 HTTP/1.1 后,客戶端在發(fā)送HTTP請(qǐng)求時(shí)頭部可以帶上 Connection:Keep-Alive ,就是告訴服務(wù)器保持連接,不要關(guān)閉TCP。當(dāng) Connection:Close 時(shí),服務(wù)器會(huì)關(guān)閉連接。

HTTP發(fā)展歷史

在總結(jié)http2之前先來回顧下http的發(fā)展歷史。以下三張圖片來自 Jerry Qu

HTTP/0.9 (1991)

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

HTTP/1.0 (1996)

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

HTTP/1.1 (1999)

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

HTTP通信過程

眾所周知,http是基于tcp之上的應(yīng)用層協(xié)議,即在tcp連接建立之后,在tcp的鏈路上傳送數(shù)據(jù)。

 

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

  1. 首先進(jìn)行TCP連接,三次握手, C --(SYN{k})--> S , S --(ACK{k+1}&SYN{j})--> C , C --ACK{j+1}--> S
  2. 客戶端發(fā)送ACK后,就會(huì)發(fā)送一個(gè)HTTP請(qǐng)求
  3. 服務(wù)端接受到ACK,確認(rèn)TCP連接建立,再接著收到HTTP請(qǐng)求,進(jìn)行解析并將結(jié)果返回客戶端。
  4. 客戶端收到HTTP請(qǐng)求結(jié)果。

在 HTTP/0.9 和 HTTP/1.0 中,第3步之后,服務(wù)端就會(huì)關(guān)閉連接,也就是TCP的四次揮手,但是在 HTTP/1.1 后,客戶端在發(fā)送HTTP請(qǐng)求時(shí)頭部可以帶上 Connection:Keep-Alive ,就是告訴服務(wù)器保持連接,不要關(guān)閉TCP。當(dāng) Connection:Close 時(shí),服務(wù)器會(huì)關(guān)閉連接。

HTTP2 的通信過程無外乎這是這個(gè)流程,但是通過TCP傳輸?shù)臄?shù)據(jù)會(huì)有不同,客戶端和服務(wù)器的行為也有了新的規(guī)則。引入了Connection、Stream、Message、Frame這四個(gè)概念,從下圖大概可以看出他們之間的關(guān)系。

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

  • Connection: 其實(shí)就是一個(gè)TCP連接
  • Stream:已建立的連接上的雙向字節(jié)流
  • Message:請(qǐng)求或者響應(yīng),由一個(gè)或多個(gè)幀組合而成
  • Frame: Message中的二進(jìn)制幀,HTTP/2通信的最小單位,后面會(huì)詳細(xì)解釋

HTTP/2 新特性

  • 二進(jìn)制分幀(Binary framing layer)
  • 多路復(fù)用 (Multiplexing)
  • 單一連接(One connection per origin)
  • 數(shù)據(jù)流優(yōu)先級(jí)(Stream prioritization)
  • 首部壓縮(Header Compression)
  • 流控 (Flow control)
  • 服務(wù)端推送(Server Push)

這些新特性的產(chǎn)生,主要是為了解決之前的問題,我們來對(duì)比下之前的 HTTP/1.1 ,看看解決了哪些問題

二進(jìn)制分幀(Binary framing layer)

二進(jìn)制分幀就是把http的數(shù)據(jù)按照規(guī)定的格式進(jìn)行封裝,類似IP和TCP的數(shù)據(jù)包, 簡(jiǎn)單畫了個(gè)承載HTTP2數(shù)據(jù)的以太幀結(jié)構(gòu),方便理解。

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

通過wireshark抓包可以看到http2的結(jié)構(gòu)

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

  • Length: 無符號(hào)的自然數(shù),24個(gè)比特表示,僅表示幀負(fù)載所占用字節(jié)數(shù),不包括幀頭所占用的9個(gè)字節(jié)。默認(rèn)大小區(qū)間為為0~16,384(2^14),一旦超過默認(rèn)最大值2^14(16384),發(fā)送方將不再允許發(fā)送,除非接收到接收方定義的SETTINGS_MAX_FRAME_SIZE(一般此值區(qū)間為2^14 ~ 2^24)值的通知。
  • Type: 8個(gè)比特表示,定義了幀負(fù)載的具體格式和幀的語義,HTTP/2規(guī)范定義了10個(gè)幀類型,這里不包括實(shí)驗(yàn)類型幀和擴(kuò)展類型幀
  • Flags: 8個(gè)比特表示,服務(wù)于具體幀類型,默認(rèn)值為0x0。有一個(gè)小技巧需要注意,一般來講,8個(gè)比特可以容納8個(gè)不同的標(biāo)志,比如,PADDED值為0x8,二進(jìn)制表示為00001000;END_HEADERS值為0x4,二進(jìn)制表示為00000100;END_STREAM值為0X1,二進(jìn)制為00000001。可以同時(shí)在一個(gè)字節(jié)中傳達(dá)三種標(biāo)志位,二進(jìn)制表示為00001101,即0x13。因此,后面的幀結(jié)構(gòu)中,標(biāo)志位一般會(huì)使用8個(gè)比特表示,若某位不確定,使用問號(hào)?替代,表示此處可能會(huì)被設(shè)置標(biāo)志位
  • R: 在HTTP/2語境下為保留的比特位,固定值為0X0
  • Stream Identifier: 無符號(hào)的31比特表示無符號(hào)自然數(shù)。0x0值表示為幀僅作用于連接,不隸屬于單獨(dú)的流。

HTTP2幀中的類型如下:

 

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

想了解每一個(gè)類型的詳細(xì)數(shù)據(jù)結(jié)構(gòu)可以參考我的另一篇文章http2幀類型詳解

通過Google Developers中的一個(gè)圖,我們可以更好的理解,HTTP2的分幀在網(wǎng)絡(luò)數(shù)據(jù)中所處的位置,以及和HTTP/1.1的不同之處。

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

HTTP/1.1中的頭部變成HEADERS類型的幀,請(qǐng)求體/回應(yīng)體變成DATA類型的幀,通過二進(jìn)制分幀,將傳輸?shù)臄?shù)據(jù)使用二進(jìn)制方式,對(duì)比文本方式減少數(shù)據(jù)量;通過不同類型的幀實(shí)現(xiàn)流控、服務(wù)器推送等功能。

多路復(fù)用 (Multiplexing) & 單一連接(One connection per origin)

我們知道在HTTP2之前,我們?nèi)绻爰涌炀W(wǎng)頁資源的加載速度,會(huì)采用同時(shí)建立多條連接的方式,但是這樣每次建立TCP連接效率比較低,并且瀏覽器往往會(huì)限制最大連接數(shù)(例如chrome的最大連接數(shù)為6)。另外在HTTP/1.1中引入了Pipeline,可以在一個(gè)TCP連接中連續(xù)發(fā)送多個(gè)請(qǐng)求,不用關(guān)心前面的響應(yīng)是否到達(dá),但是服務(wù)器必須要按照收到請(qǐng)求的順序來進(jìn)行響應(yīng),這樣一旦前面的請(qǐng)求阻塞,后來的請(qǐng)求也將不能及時(shí)回應(yīng)。

HTTP2中,因?yàn)樾碌亩M(jìn)制幀的使用,使得可以輕松復(fù)用單個(gè)TCP連接。客戶端和服務(wù)器可以將 HTTP 消息分解為互不依賴的幀,然后交錯(cuò)發(fā)送,最后再在另一端把它們重新組裝起來。

還是 Google Developers的圖:

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

可以看到我們可以并行交錯(cuò)的發(fā)送多個(gè)響應(yīng)和請(qǐng)求,并且使用同一個(gè)TCP連接,沒有先后順序,每個(gè)幀中攜帶有如何組裝的信息,客戶端會(huì)等某項(xiàng)工作所需要的所有的資源都就緒之后再執(zhí)行。

數(shù)據(jù)流優(yōu)先級(jí)(Stream prioritization)

由于可以進(jìn)行單連接復(fù)用,服務(wù)器和客戶端的幀都是交錯(cuò)發(fā)送,對(duì)于發(fā)送給服務(wù)器的幀,為了解決哪些該先處理,哪些該后處理,因此引入了數(shù)據(jù)流的優(yōu)先級(jí),服務(wù)器根據(jù)優(yōu)先級(jí)來分配資源。例如優(yōu)先級(jí)高的獲得更多的CPU和帶寬資源。那么優(yōu)先級(jí)是如何標(biāo)示的呢?還記得前面的幀類型中有一個(gè)Type為PRIORITY,這種類型的幀就是為了告訴服務(wù)器這個(gè)stream的優(yōu)先級(jí),此外HEADERS幀中也包含了優(yōu)先級(jí)信息。

HTTP/2通過父依賴和權(quán)重來標(biāo)示優(yōu)先級(jí),每一個(gè)stream會(huì)標(biāo)示一個(gè)父stream id,沒有標(biāo)示的默認(rèn)為虛擬的root stream,這樣按照這種依賴關(guān)系構(gòu)建一個(gè)依賴樹,樹上層的stream權(quán)重較高,同一層的stream會(huì)有一個(gè)weight來區(qū)分資源分配比。。

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

上圖是依賴樹的一些示例,從左到右,共四棵樹。

  • 第一個(gè)兩個(gè)stream A 和 B,沒有標(biāo)明父stream,默認(rèn)依賴虛擬的root節(jié)點(diǎn),A、B處于同一層,優(yōu)先級(jí)相同,根據(jù)權(quán)重分配資源,A分到 12/(12+4)=3/4 資源,B分到 1/4 資源。
  • 第二個(gè)D和C有層級(jí)結(jié)構(gòu),C的父級(jí)是D,那么服務(wù)器拿完整資源優(yōu)先處理D,然后再處理C。
  • 第三個(gè),服務(wù)器先處理D,再處理C,然后處理A和B,A分到 3/4 資源,B分到 1/4 資源。
  • 第四個(gè),先處理D,再講資源對(duì)半分處理E和C,之后再按照權(quán)重處理A和B

需要注意的一點(diǎn)是,流優(yōu)先級(jí)并不是強(qiáng)制約束,當(dāng)優(yōu)先級(jí)高的流阻塞時(shí),并不能不讓服務(wù)器處理優(yōu)先級(jí)低的流

首部壓縮 (Header Compression)

由于當(dāng)前網(wǎng)站內(nèi)容越來越復(fù)雜,單個(gè)頁面的請(qǐng)求數(shù)基本都是幾十個(gè)甚至上百,每個(gè)請(qǐng)求都要帶上客戶端或者用戶的標(biāo)識(shí),例如:UA,cookie等頭部數(shù)據(jù),請(qǐng)求數(shù)量多了以后,傳輸http頭部消耗的流量也非常可觀,并且頭部數(shù)據(jù)中大部分都是相同的,這就是赤裸裸的浪費(fèi)呀。于是產(chǎn)生了頭部壓縮技術(shù)來節(jié)省流量。

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

  • 維護(hù)一份相同的靜態(tài)字典(Static Table),包含常見的頭部名稱,以及特別常見的頭部名稱與值的組合
  • 維護(hù)一份相同的動(dòng)態(tài)字典(Dynamic Table),可以動(dòng)態(tài)地添加內(nèi)容
  • 支持基于靜態(tài)哈夫曼碼表的哈夫曼編碼(Huffman Coding)

靜態(tài)字典

靜態(tài)字典就是把常用的頭部映射為字節(jié)較短的索引序號(hào),如下圖所示,截取了前面幾個(gè)映射,全部定義可以看 Static Table Definition

HTTP2總結(jié)及簡(jiǎn)單實(shí)踐

例如當(dāng)頭部有個(gè)字段是 :method: GET ,那么查表可知,可以用序號(hào)2標(biāo)識(shí),于是這個(gè)字段的數(shù)據(jù)就是 0000010 (2的二進(jìn)制表示)

動(dòng)態(tài)字典

靜態(tài)字典能表示的頭部數(shù)據(jù)畢竟有限,壓縮率也不會(huì)高。但是對(duì)于一個(gè)站點(diǎn)來講,和某個(gè)用戶交互時(shí)會(huì)發(fā)生非常多的請(qǐng)求,但是每次請(qǐng)求頭部差別不大,會(huì)有很多重復(fù)數(shù)據(jù),因?yàn)橛脩艉蜑g覽器的標(biāo)識(shí)是不變的。那么我們可以針對(duì)一次HTTP2的連接生成一個(gè)可添加映射的動(dòng)態(tài)字典,這樣再后面的連接中就可以使用動(dòng)態(tài)字典中的序號(hào)。動(dòng)態(tài)字典的生成過程其實(shí)就是通知對(duì)方添加映射,客戶端可以通知服務(wù)端添加,反之亦可。

具體的通知方式就是按照協(xié)議規(guī)定的格式傳輸數(shù)據(jù)。

Huffman Coding

哈弗曼編碼的特性是出現(xiàn)頻率越高,編碼長(zhǎng)度越短。HTTP2協(xié)議中根據(jù)大量的請(qǐng)求頭部數(shù)據(jù)樣本生成了一種canonical Huffman code,具體在 Huffman Code 列出。

流控 (Flow control)

HTTP/2 流量控制的目標(biāo),在流量窗口初始值的約束下,給予接收端以全權(quán),控制當(dāng)下想要接受的流量大小。

算法:

  • 兩端(收發(fā))保有一個(gè)流量控制窗口(window)初始值。
  • 發(fā)送端每發(fā)送一個(gè)DATA幀,就把window遞減,遞減量為這個(gè)幀的大小,要是window小于幀大小,那么這個(gè)幀就必須被拆分。如果window等于0,就不能發(fā)送任何幀
  • 接收端可以發(fā)送 WINDOW_UPDATE幀給發(fā)送端,發(fā)送端以幀內(nèi)指定的Window Size Increment作為增量,加到window上

服務(wù)端推送 (Server Push)

流程:

  • 客戶端在交換 SETTINGS 幀時(shí),設(shè)置字段 SETTINGS_ENABLE_PUSH(0x2) 為1顯式允許服務(wù)器推送
  • 服務(wù)器在接受到請(qǐng)求時(shí),分析出要推送的資源,先發(fā)個(gè) PUSH_PROMISE 幀給瀏覽器
  • 然后再發(fā)送各個(gè)response header和response body
  • 瀏覽器收到 PUSH_PROMISE 幀時(shí),根據(jù)header block fragment字段里的url,可以知道當(dāng)前有沒有緩存,從而判斷是否要接收。如果不要,瀏覽器就要發(fā)送個(gè) RST_STREAM 來終止服務(wù)器推送

問題:

  • 流量浪費(fèi)。若瀏覽器有緩存,不要這個(gè)推送,就會(huì)出現(xiàn)浪費(fèi)流量的現(xiàn)象,因?yàn)檎麄€(gè)過程都是異步的,在服務(wù)器接收到RST_STREAM時(shí),響應(yīng)很有可能部份發(fā)出或者全部發(fā)出了。

HTTP/2簡(jiǎn)單實(shí)踐

Okhttp是一個(gè)java生態(tài)中有名的的http client,由于其簡(jiǎn)單易用,性能較好,支持http2。下面用這個(gè)工具來實(shí)踐下,因?yàn)楸救瞬┛鸵呀?jīng)在nginx上配置了http2,就拿本博客來實(shí)驗(yàn)下。

 

  1. public class Http2Example { 
  2.     final static OkHttpClient client = new OkHttpClient.Builder().build(); 
  3.     public static void main(String[] args) { 
  4.         Request request = new Request.Builder() 
  5.                 .url("https://blog.fliaping.com"
  6.                 .build(); 
  7.         try { 
  8.             Response response = client.newCall(request).execute(); 
  9.             System.out.println(JSON.toJSONString(response.protocol())); 
  10.             System.out.println(response.headers().toString()); 
  11.             System.out.println(response.body().string()); 
  12.         } catch (IOException e) { 
  13.             e.printStackTrace(); 
  14.         } 
  15.     } 

用過Okhttp的同學(xué)就會(huì)發(fā)現(xiàn),這跟平時(shí)用的方法一樣啊,沒有任何區(qū)別,是的沒錯(cuò),就是沒有任何區(qū)別。別的不多說,執(zhí)行下看看,不幸的是你會(huì)發(fā)現(xiàn)protocol還是http1.1,并不是h2,這是怎么回事?這是因?yàn)镠TTP2新加入了ALPN(Application Layer Protocol Negotiation),從字面意思理解就是應(yīng)用層協(xié)議協(xié)商,即雙方商量下用哪個(gè)協(xié)議。不幸的是jdk8是在2014年發(fā)布的,當(dāng)時(shí)HTTP2協(xié)議還沒出生,幸運(yùn)的是通過第三方j(luò)ar包就可以支持ALPN。另外jdk9已經(jīng)支持了HTTP2,雖然還沒正式發(fā)布,但是我們可以試用下JDK 9 Early-Access Builds。

jdk7和jdk8通過添加jvm參數(shù)加入第三方alpn支持包,注意版本不能搞錯(cuò),jdk7使用 alpn-boot-7.*.jar ,jdk8使用 alpn-boot-8.*.jar ,這里有版本對(duì)應(yīng)關(guān)系 alpn-versions

 

  1. # jdk8 
  2. -Xbootclasspath/p:/home/payne/Downloads/alpn-boot-8.1.11.v20170118.jar 
  3. # jdk7 
  4. -Xbootclasspath/p:/home/payne/Downloads/alpn-boot-7.1.3.v20150130.jar 
  5. # jdk9 
  6. # 使用jdk9平臺(tái)時(shí),注意okhttp版本大于3.3.0  
  7. # https://mvnrepository.com/artifact/org.mortbay.jetty.alpn/alpn-boot 

 

責(zé)任編輯:未麗燕 來源: Payne's Blog
相關(guān)推薦

2009-06-29 14:19:43

Strust2實(shí)踐

2019-10-15 08:00:00

HTTP2HTTP前端

2015-09-23 10:14:48

iOS 代碼實(shí)踐

2023-10-11 18:30:38

2018-11-14 15:00:08

HTTP程序員前端

2015-08-13 10:31:18

Java 9新功能

2016-10-21 10:36:54

http2spdynode.js

2010-06-12 17:37:18

UML實(shí)踐指南

2011-11-02 15:42:27

2010-02-01 09:55:42

Python HTTP

2024-04-30 09:10:55

HTTP2TCP內(nèi)網(wǎng)

2009-03-17 10:11:33

2010-05-24 09:49:47

ADO.NET

2022-09-01 08:17:15

Gateway微服務(wù)網(wǎng)關(guān)

2019-05-05 08:43:07

Windows認(rèn)證密碼

2017-05-08 08:20:34

False注入MySQLSQL注入

2024-02-02 09:28:21

FrankenPHP應(yīng)用

2018-12-18 10:07:41

Spring Boot服務(wù)器HTTP2

2012-02-02 13:04:50

JavaSpring

2014-03-12 10:13:00

iOSSEL對(duì)象
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 罗宾被扒开腿做同人网站 | 色就是色欧美 | 福利一区二区在线 | 国产精品久久久久久久久久妇女 | 欧美精品一区二区三区在线播放 | 欧美黄色一级毛片 | 欧美中文视频 | 曰批视频在线观看 | 黄色精品 | 91视频精选 | 成人福利网站 | 91精品国产综合久久婷婷香蕉 | 福利网址| 九九久久在线看 | 综合精品在线 | 中文字幕综合 | 免费在线看黄视频 | 亚洲激情在线 | 亚洲欧美日韩在线 | 在线午夜电影 | 蜜桃在线视频 | 做a视频在线观看 | 99爱在线观看 | 午夜综合 | 亚洲欧美久久 | 午夜精品久久久久久久久久久久久 | 91欧美精品成人综合在线观看 | 欧美日韩理论 | 黄在线| 欧美在线视频不卡 | 波多野结衣在线观看一区二区三区 | 欧美一极视频 | 精品av | 日韩精品久久久久久 | 人人操日日干 | 国产乱码精品一区二区三区中文 | 国产免费一区二区 | 欧美一区二区三区在线 | 99精品国自产在线观看 | 在线免费毛片 | 91在线精品视频 |