Ⅰ-Introduce
- 先來講講這篇文章的誘因,一個(gè)安卓開發(fā)朋友去面試,有了下面的對(duì)話:
- 面試官:"一個(gè)界面有十個(gè)請(qǐng)求,那么十個(gè)請(qǐng)求建立了幾次連接?"
- 朋友:"巴拉巴拉......"
- 面試官:"切!只有一個(gè),菜!"
- 朋友:"嗯...",此時(shí)內(nèi)心OS:"TM為啥只有一個(gè),我不服,這擺明為難我!!!"
-
(一場(chǎng)面試愉快的結(jié)束了...)
- 個(gè)人認(rèn)為:不講場(chǎng)景,不基于協(xié)議討論這個(gè)問題就是耍流氓,擺明不想真招人!!!
- 我聽到了這個(gè)問題后就想自己在學(xué)習(xí)了解下為什么只有一次,當(dāng)然我內(nèi)心是想證明面試官是錯(cuò)的
- 分析一波文章寫的時(shí)候的心路歷程 : TCP > HTTP 1.0 & HTTP 1.1 > HTTP 2.0 > 得出結(jié)論
- 結(jié)論在最后,也可以直接看結(jié)論!!!!
- 如果我理解的哪里有錯(cuò)誤,請(qǐng)一定告訴我,阿里嘎多~
Ⅱ-TCP協(xié)議
1 簡(jiǎn)介
-
各個(gè)協(xié)議的作用和關(guān)系
- 以太網(wǎng)(Ethernet)協(xié)議:解決局域網(wǎng)內(nèi)點(diǎn)對(duì)點(diǎn)通信
- IP協(xié)議: 解決多個(gè)局域網(wǎng)之間的通信
- TCP協(xié)議: TCP 是以太網(wǎng)協(xié)議和IP協(xié)議的上層協(xié)議辆亏,也是應(yīng)用層協(xié)議的下層協(xié)議
- TCP 協(xié)議: 保證數(shù)據(jù)通信的完整性和可靠性,防止丟包。IP協(xié)議只是一個(gè)地址協(xié)議,并不保證數(shù)據(jù)包的完整栏尚。如果路由器丟包(比如緩存滿了,新進(jìn)來的數(shù)據(jù)包就會(huì)丟失),就需要發(fā)現(xiàn)丟了哪一個(gè)包,以及如何重新發(fā)送這個(gè)包.這就要依靠TCP協(xié)議汗盘。
2 數(shù)據(jù)包
-
TCP數(shù)據(jù)包
- 以太網(wǎng)數(shù)據(jù)包(packet)的大小是固定的,從1518字節(jié),增加到1522字節(jié)和措。22字節(jié)是以太網(wǎng)頭信息(head),其中1500 字節(jié)是負(fù)載(payload).
- IP數(shù)據(jù)包在以太網(wǎng)數(shù)據(jù)包的payload中,他也有自己的頭信息,也是20字節(jié),所以IP數(shù)據(jù)包的負(fù)載為1480字節(jié)
- TCP數(shù)據(jù)包又在IP數(shù)據(jù)包的payload中,20字節(jié)的頭信息,實(shí)際負(fù)載只有1460字節(jié),另外IP&TCP協(xié)議往往有額外的頭信息应又,所以TCP負(fù)載實(shí)際為1400字節(jié)左右问畅。
所以一個(gè)packet頭信息就要占100多字節(jié),如果是條1500字節(jié)的信息,那就不得不分成兩個(gè)packet,所以壓縮頭信息,提高傳輸速度成為HTTP/2協(xié)議的重點(diǎn)需要改進(jìn)的點(diǎn)
-
TCP數(shù)據(jù)包編號(hào):SEQ
- 一個(gè)超過1400字節(jié)的數(shù)據(jù),必須拆成多個(gè)包進(jìn)行傳輸數(shù)據(jù),那么就需要把拆開的數(shù)據(jù)包再組合起來,那么數(shù)據(jù)包編號(hào)(SEQ)也就有作用了,既能將傳輸?shù)臄?shù)據(jù)按照一定的順序組裝起來,又能確定丟包丟的是哪個(gè)包
- 規(guī)則:
* 第一個(gè)包的編號(hào)是隨機(jī)的,假設(shè)是0號(hào)包,第一個(gè)包內(nèi)存儲(chǔ)的字節(jié)是100字節(jié)
* 那么第二個(gè)包的編號(hào)就是100
* 也可以由第二個(gè)包的編號(hào)和第一個(gè)包的編號(hào)確定第一個(gè)包內(nèi)包含的數(shù)據(jù)負(fù)載是多少
-
數(shù)據(jù)包組裝
- 數(shù)據(jù)包的組裝不由應(yīng)用程序完成,有操作系統(tǒng)完成,操作系統(tǒng)將數(shù)據(jù)包組裝好再給應(yīng)用程序使用,TCP數(shù)據(jù)包里有個(gè)port參數(shù),數(shù)據(jù)包完成組裝,操作系統(tǒng)根據(jù)端口信息,將packet轉(zhuǎn)交給監(jiān)聽特定端口號(hào)的應(yīng)用程序
- 應(yīng)用程序收到組裝好的原始數(shù)據(jù)艾栋,以瀏覽器為例爆存,就會(huì)根據(jù) HTTP 協(xié)議的Content-Length字段正確讀出一段段的數(shù)據(jù)。這也意味著裹粤,一次 TCP通信可以包括多個(gè)HTTP通信
3 數(shù)據(jù)傳輸和丟包處理
- 大致知道了數(shù)據(jù)包的組裝過程和組成,那么問題就是一次服務(wù)器發(fā)送數(shù)據(jù)包一次發(fā)多少,發(fā)多少有什么決定這個(gè)問題
-
一次發(fā)送多少個(gè)數(shù)據(jù)包?
- 當(dāng)然是發(fā)送數(shù)據(jù)包越快越好,但是寬帶小,路由器過熱等等導(dǎo)致的可同時(shí)傳輸?shù)臄?shù)據(jù)包在一定時(shí)間是一定的,這時(shí)候再發(fā)送超過可發(fā)送上線的數(shù)據(jù)包就會(huì)導(dǎo)致丟包
- 最理想狀態(tài),在線路允許情況下,達(dá)到傳輸速度最大化
- TCP協(xié)議設(shè)計(jì)了一個(gè)慢啟動(dòng)機(jī)制,既開始發(fā)送較慢,根據(jù)丟包情況決定傳輸速率,不丟包增加傳輸速度,丟包就降低傳輸速度,那么傳輸多少個(gè)包的問題就得到了解決
- Linux 設(shè)定剛開始通信的時(shí)候,發(fā)送方第一次發(fā)送10個(gè)數(shù)據(jù)包,然后等待接收方的確認(rèn),默認(rèn)接收方每收到2個(gè)數(shù)據(jù)包,就發(fā)送一個(gè)確認(rèn)消息(ACK)
Ⅲ-HTTP 1.0 & HTTP 1.1
1.HTTP(超文本傳輸協(xié)議)簡(jiǎn)介
真的只是簡(jiǎn)介,是我就跳過了
-
特點(diǎn)
- HTTP 協(xié)議簡(jiǎn)單终蒂,使得 HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快
- HTTP 允許傳輸任意類型的數(shù)據(jù)對(duì)象遥诉。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記
- 無連接:無連接的含義是限制每次連接只處理一個(gè)請(qǐng)求拇泣。服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接矮锈。采用這種方式可以節(jié)省傳輸時(shí)間
-
組成
- HTTP協(xié)議:一個(gè)基于請(qǐng)求與響應(yīng)模式的霉翔、無狀態(tài)的、應(yīng)用層的協(xié)議苞笨,痴洌基于TCP的連接方式
2.HTTPの請(qǐng)求
- HTTP請(qǐng)求由三部分組成
- 請(qǐng)求行
- 消息報(bào)頭
- 請(qǐng)求正文
-
請(qǐng)求行
- 請(qǐng)求行以一個(gè)方法符號(hào)開頭,以空格分開,后面跟著請(qǐng)求的 URI 和協(xié)議的版本子眶,格式如下:Method Request-URI(統(tǒng)一資源標(biāo)識(shí)符,既URL) HTTP-Version CRLF(表示回車和換行)
- 請(qǐng)求方法-Method
* GET & POST (我也就只用過這兩個(gè)....)
* HEAD作用: 只請(qǐng)求資源的首部/檢查超鏈接的有效性/檢查網(wǎng)頁是否被修改
* PUT:請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源
* DELETE 請(qǐng)求服務(wù)器刪除一個(gè)資源
* TRACE 請(qǐng)求服務(wù)器回送收到的請(qǐng)求消息,主要用于測(cè)試或者診斷
* CONNECT (Keep-Alive)
* OPTIONS 請(qǐng)求查詢服務(wù)區(qū)的性能,查詢與資源相關(guān)的選項(xiàng)和需求
3.HTTPの響應(yīng)
- HTTP響應(yīng)也是由三個(gè)部分組成,分別是:狀態(tài)行序芦、消息報(bào)頭臭杰、響應(yīng)正文
- 狀態(tài)行
- 格式: HTTP-Version Status-Code Reason-Phrase(表示狀態(tài)代碼的文本描述) CRLF
- status-code
* 200 OK //客戶端請(qǐng)求成功
* 400 Bad Request //客戶端請(qǐng)求有語法錯(cuò)誤,不能被服務(wù)器所理解
* 401 Unauthorized //請(qǐng)求未經(jīng)授權(quán)谚中,這個(gè)狀態(tài)代碼必須和
WWW-Authenticate 一起使用
* 403 Forbidden //服務(wù)器收到請(qǐng)求渴杆,但是拒絕提供服務(wù)
* 404 Not Found //請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的 URL
* 500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
* 503 Server Unavailable//服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求宪塔,一段時(shí)間后磁奖,//可能恢復(fù)正常
- 消息報(bào)頭
* Accept:用于指定客戶端接受哪些類型的信息
* Accept-Charset 請(qǐng)求報(bào)頭域用于指定客戶端接受的字符集 (未設(shè)置,則是任何字符集都可接受)
* Accept-Encoding 可接受的內(nèi)容編碼,沒有服務(wù)器假定客戶端對(duì)各種內(nèi)容編 碼都可以接受
* Accept-Language
* Authorization 當(dāng)瀏覽器訪問一個(gè)頁面時(shí) ,如 果收到服務(wù)器的響應(yīng)代碼為 401(未授權(quán))某筐,可以發(fā)送一個(gè)包含 Authorization,要求服務(wù)器對(duì)其進(jìn)行驗(yàn)證比搭。
* Host(必需)
* User-Agent
4.補(bǔ)充
- 高層協(xié)議
- 文件傳輸協(xié)議 FTP
- 電子郵件傳輸協(xié)議 SMTP
- 域名系統(tǒng)服務(wù) DNS
- 網(wǎng)絡(luò)新聞傳輸協(xié)議NNTP
Ⅳ-HTTP 2.0
- 重點(diǎn)來了,打起精神來
1. HTTP 2.0 需要解決什么問題
1. 相對(duì)于使用 TCP 的HTTP1.1,用戶在大多數(shù)情況下的感知延遲要有實(shí)質(zhì)上、可度量的改進(jìn)南誊;
2. 解決 HTTP 中的“隊(duì)首阻塞”問題身诺;
> 隊(duì)首阻塞會(huì)在下面的HTTP Pipelining解釋
3. 并行操作無需與服務(wù)器建立多個(gè)連接,從而改進(jìn)TCP的利用率弟疆,特別是擁塞控制方面戚长;
4. 保持 HTTP 1.1 的語義,利用現(xiàn)有文檔怠苔,包括(但不限于)HTTP 方法同廉、狀態(tài)碼、URI柑司,以及首部字段(既向下兼容)
5. 解決突破HTTP1.0 & HTTP1.1 的性能限制,改進(jìn)傳輸性能迫肖,實(shí)現(xiàn)低延遲和高吞吐量
2.主要改變
- 通過支持首部字段壓縮和在同一連接上發(fā)送多個(gè)并發(fā)消息,讓應(yīng)用更有效地利用網(wǎng)絡(luò)資源攒驰,減少感知的延遲時(shí)間蟆湖。而且,它還支持服務(wù)器到客戶端的主動(dòng)推送機(jī)制
3.二進(jìn)制分幀數(shù)據(jù)層
- 作用:封裝HTTP消息,并在客戶端與服務(wù)器之間傳輸,將所有傳輸?shù)男畔⒎指顬楦〉南⒑蛶7啵?duì)它們采用二進(jìn)制格式的編碼
- 組成:幀 & 消息 & 流
1. 組成:流既通道,通道內(nèi)雙向傳輸消息,消息由幀組成
2. 流:連接中的一個(gè)虛擬信道隅津,可以承載雙向的消息;每個(gè)流都有一個(gè)唯一的整數(shù)標(biāo)識(shí)符(1劲室、2…n)
3. 消息:是指邏輯上的HTTP消息伦仍,比如請(qǐng)求、響應(yīng)等很洋,由一或多個(gè)幀組成
4. 幀:HTTP 2.0 通信的最小單位充蓝,每個(gè)幀包含幀首部,至少也會(huì)標(biāo)識(shí)出當(dāng)前幀所屬的流,承載著特定類型的數(shù)據(jù),如HTTP的header 負(fù)荷等等,**所有首部數(shù)據(jù)都會(huì)被壓縮**
- 二進(jìn)制分幀層實(shí)現(xiàn)了多項(xiàng)請(qǐng)求和響應(yīng),可以把消息分級(jí)為互不依賴的幀,亂序發(fā)送
1. 可以并行交錯(cuò)地發(fā)送請(qǐng)求谓苟,請(qǐng)求之間互不影響官脓;
2. 可以并行交錯(cuò)地發(fā)送響應(yīng),響應(yīng)之間互不干擾涝焙;
3. 只使用一個(gè)連接即可并行發(fā)送多個(gè)請(qǐng)求和響應(yīng)卑笨;
4. 消除不必要的延遲,從而減少頁面加載的時(shí)間仑撞;
5. 不必再為繞過 HTTP 1.x 限制而多做很多工作
- 作用
- HTTP 2.0 的二進(jìn)制分幀機(jī)制解決了HTTP1.x中存在的隊(duì)首阻塞問題湾趾,也消除了并行處理和發(fā)送請(qǐng)求及響應(yīng)時(shí)對(duì)多個(gè)連接的依賴。
- 有了新的分幀機(jī)制后派草,HTTP 2.0不再依賴多個(gè)TCP連接去實(shí)現(xiàn)多流并行了。每個(gè)數(shù)據(jù)流都拆分成很多幀,而這些幀可以交錯(cuò)铛楣,還可以分別優(yōu)先級(jí)近迁。HTTP2.0連接都是持久化的,而且客戶端與服務(wù)器之間也只需要一個(gè)連接即可簸州。
- 大多數(shù)HTTP 連接的時(shí)間都很短鉴竭,而且是突發(fā)性的,但TCP 只在長(zhǎng)時(shí)間連接傳輸大塊數(shù)據(jù)時(shí)效率才最高岸浑。HTTP 2.0 通過讓所有數(shù)據(jù)流共用同一個(gè)連接搏存,可以更有效地使用TCP 連接。
4.服務(wù)器推送
- HTTP 2.0 新增的一個(gè)強(qiáng)大的新功能矢洲,就是服務(wù)器可以對(duì)一個(gè)客戶端請(qǐng)求發(fā)送多個(gè)響應(yīng)璧眠。服務(wù)器向客戶端推送資源無需客戶端明確地請(qǐng)求
5.HTTP Pipelining
- HTTP Pipelining:其實(shí)是把多個(gè)HTTP請(qǐng)求放到一個(gè)TCP連接中一一發(fā)送,而在發(fā)送過程中不需要等待服務(wù)器對(duì)前一個(gè)請(qǐng)求的響應(yīng)读虏;只不過责静,客戶端還是要按照發(fā)送請(qǐng)求的順序來接收響應(yīng)。但就像在超市收銀臺(tái)或者銀行柜臺(tái)排隊(duì)時(shí)一樣盖桥,你并不知道前面的顧客是干脆利索的還是會(huì)跟收銀員/柜員磨蹭到世界末日(譯者注:不管怎么說灾螃,服務(wù)器(即收銀員/柜員)是要按照順序處理請(qǐng)求的,如果前一個(gè)請(qǐng)求非常耗時(shí)(顧客磨蹭)揩徊,那么后續(xù)請(qǐng)求都會(huì)受到影響)腰鬼,這就是所謂的隊(duì)首阻塞(Head of line blocking)。
V-結(jié)論
- 如果面試官問的問題是基于TCP協(xié)議,那么我認(rèn)為:多次請(qǐng)求是可以保持一次連接的,因?yàn)槊看蝿?chuàng)建新的TCP連接很占資源和性能
- 如果面試官問的問題是基于HTTP1.x協(xié)議,那么如果在設(shè)置connection:keep-alive的前提下,是存在多次請(qǐng)求保持一次連接的,但針對(duì)同一域名的請(qǐng)求有一定的數(shù)量限制(maxKeepAliveRequests),超過限制的請(qǐng)求會(huì)被阻塞,我覺得多次請(qǐng)求保持一次連接是不能保證的,且存在系統(tǒng)資源無效占用等問題,還要設(shè)置connectionTimeout最大間隔時(shí)間,如果超過最大時(shí)間間隔,連接會(huì)被關(guān)閉,所以在不設(shè)置的前提下,只有一次連接我是不服氣的
- 如果面試官問的問題是基于HTTP2協(xié)議,那呢我認(rèn)為:是一次連接的,二進(jìn)制分幀層解決了雙向并行交錯(cuò)地發(fā)送請(qǐng)求和響應(yīng),而且優(yōu)化延遲也是通過減少創(chuàng)建TCP連接而設(shè)計(jì)的
so,這個(gè)面試官給的肯定回答也只是五五開嘍!!!(盧姥爺曾經(jīng)而是體面人~)
Ⅵ 參考文檔
- TCP
- 阮一峰TCP協(xié)議簡(jiǎn)介: http://www.ruanyifeng.com/blog/2017/06/tcp-protocol.html
- HTTP 2.0
- HTTP 2.0 協(xié)議詳解 : https://blog.csdn.net/zqjflash/article/details/50179235
- HTTP的現(xiàn)狀 : https://ye11ow.gitbooks.io/http2-explained/content/part2.html