概述
HTTP是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,有名超文本鏈接協(xié)議紊撕。我們?cè)陂_發(fā)中請(qǐng)求數(shù)據(jù)罢荡,發(fā)送數(shù)據(jù)都會(huì)用到HTTP協(xié)議。
與HTTP相關(guān)的協(xié)議
與HTTP相關(guān)聯(lián)的協(xié)議有很多,其中TCP区赵、IP惭缰、DNS尤為重要。
IP:網(wǎng)際協(xié)議
作用:把各種數(shù)據(jù)包傳送給對(duì)方笼才。
而要保證數(shù)據(jù)傳輸?shù)綄?duì)方那里漱受,需要兩個(gè)重要條件,IP地址和電腦地址(網(wǎng)卡地址)骡送。
ARP:是一種用以解析地址的協(xié)議昂羡,根據(jù)通信方的IP地址就可以反查出對(duì)應(yīng)的電腦地址。
TCP
作用于傳輸層各谚,提供可靠的字節(jié)流服務(wù)紧憾。
具體參考三四握手、四次揮手
DNS
作用:作用于應(yīng)用層昌渤,提供域名到IP地址之間的解析服務(wù)赴穗。
DNS協(xié)議提供通過域名查找IP地址,或者通過IP地址查找匿名服務(wù)膀息。
客戶端和服務(wù)端通信HTTP做了什么
HTTP報(bào)文
- 請(qǐng)求報(bào)文:請(qǐng)求方法般眉、請(qǐng)求URI、協(xié)議版本潜支、可選的請(qǐng)求首部字段甸赃、內(nèi)容實(shí)體構(gòu)成的。
- 響應(yīng)報(bào)文:協(xié)議版本冗酿、狀態(tài)碼埠对、解釋狀態(tài)碼的原因短語、可選的響應(yīng)首部
- 通知報(bào)文
不保存狀態(tài)
HTTP是一種無狀態(tài)協(xié)議裁替。自身不對(duì)請(qǐng)求和響應(yīng)之間的通信狀態(tài)進(jìn)行保存项玛。HTTP/1.1雖然是無狀態(tài)協(xié)議,但為了實(shí)現(xiàn)期望的保持狀態(tài)功能弱判,引入了Cookie技術(shù)襟沮。有了Cookie在使用HTTP協(xié)議通信,就可以管理狀態(tài)了昌腰。
Cookie
Cookie是通過在請(qǐng)求和響應(yīng)報(bào)文中寫入Cookie信息來控制客戶端的狀態(tài)开伏。根據(jù)服務(wù)端發(fā)送的響應(yīng)報(bào)文內(nèi)的一個(gè)叫做Set-Cookie的首部字段信息,通知客戶端保存Cookie.當(dāng)下次客戶端再往該服務(wù)器發(fā)送請(qǐng)求時(shí)遭商,客戶端會(huì)自動(dòng)在請(qǐng)求報(bào)文中加入Cookie值后發(fā)送出去(由于我是做iOS端的固灵,不太了解Web這塊,我所在公司的項(xiàng)目是手動(dòng)存儲(chǔ)Cookie的劫流,具體是否會(huì)在第二次請(qǐng)求時(shí)自動(dòng)發(fā)送巫玻,有待驗(yàn)證)暑认。
持久鏈接
HTTP/1.1和部分HTTP/1.0支持持久鏈接,也成為HTTP keep-alive大审,持久鏈接的特點(diǎn)就是只要任意一方?jīng)]有明確提出斷開鏈接,則保持TCP鏈接狀態(tài)座哩。
管線化
持久連接使得多數(shù)請(qǐng)求以管線化方式發(fā)送成為可能徒扶。從前發(fā)送請(qǐng)求需要等待并且受到相應(yīng),才能發(fā)送下一個(gè)請(qǐng)求根穷。管線化技術(shù)出現(xiàn)后姜骡,不需要等待響應(yīng)就可以直接發(fā)送下一個(gè)請(qǐng)求。
WebSocket
一旦Web服務(wù)器與客戶單建立起WebSocket協(xié)議的通信連接屿良,之后所有的通信都依靠這個(gè)專用協(xié)議進(jìn)行圈澈。通信過程可以相互發(fā)送JSON、XML尘惧、HTML或者圖片等任意格式數(shù)據(jù)康栈。
主要特點(diǎn)
- 推送功能
- 減少通信量(TCP連接消耗、WebSocket首部信息很小喷橙,通信量猩睹础)
期盼已久的HTTP/2.0
HTTP/2.0是在SPDY基礎(chǔ)上行程的下一代互聯(lián)網(wǎng)通信協(xié)議。HTTP/2.0的目的是支持請(qǐng)求與相應(yīng)的多路復(fù)用來減少延遲贰逾,并且通過壓縮HTTP首部字段將協(xié)議開銷降低悬荣,同時(shí)增加請(qǐng)求優(yōu)先級(jí)和服務(wù)端推送支持。
二進(jìn)制分幀層
二進(jìn)制分幀層疙剑,是HTTP/2.0性能增強(qiáng)的核心氯迂。
HTTP/1.x在應(yīng)用層以純文本的形式進(jìn)行通信,HTTP/2.0將所有的傳輸信息分割為更小的消息和幀言缤,并對(duì)它們采用二進(jìn)制格式編碼嚼蚀。所以,客戶端和服務(wù)端都需要引入新的二進(jìn)制編碼和解碼機(jī)制轧简。
幀(frame)
HTTP/2.0通信的最小單位驰坊,包括幀首部、流標(biāo)識(shí)符哮独、優(yōu)先值等拳芙。
其中,幀類型又分為:
- DATA:用于傳輸HTTP消息體皮璧;
- HEADERS:用于傳輸首部字段舟扎;
- SETTINGS:用于約定客戶端和服務(wù)端的配置數(shù)據(jù)。比如設(shè)置初識(shí)的雙向流量控制窗口大秀参瘛睹限;
- WINDOW_UPDATE:用于調(diào)整個(gè)別流或個(gè)別連接的流量譬猫;
- PRIORITY:用于指定或重新指定引用資源的優(yōu)先級(jí);
- RST_STREAM:用于通知流的非正常中指羡疗。
- PUSH_PROMISE:服務(wù)端推送許可染服。
- PING:用于計(jì)算往返時(shí)間。
- GOAWAY:用于通知對(duì)端停止在當(dāng)前連接中創(chuàng)建流叨恨。
消息(message)
消息是指邏輯上的HTTP消息(請(qǐng)求/響應(yīng))柳刮。一系列數(shù)據(jù)幀組成了一個(gè)完整的消息。比如一系列DATA幀和一個(gè)HEADERS幀組成了請(qǐng)求消息痒钝。
流(stream)
流是連接中的一個(gè)虛擬信道秉颗,可以承載雙向消息傳輸。每個(gè)流有唯一證書標(biāo)識(shí)符送矩。為了防止兩斷流的ID沖突蚕甥,客戶端發(fā)起的流具有奇數(shù)ID,服務(wù)端發(fā)起的流具有偶數(shù)ID栋荸。
所有HTTP/2.0通信都在一個(gè)TCP連接上完成菇怀,這個(gè)鏈接可以承載任務(wù)數(shù)量的雙向數(shù)據(jù)流Stream。每個(gè)數(shù)據(jù)流以消息的形式發(fā)送蒸其,而消息由一或者多個(gè)幀組成敏释,這些幀可以亂序發(fā)送,然后根據(jù)每個(gè)幀首部的流標(biāo)識(shí)符重新組裝摸袁。
二進(jìn)制分幀層保留了HTTP的語義不受影響钥顽,包括首部、方法等靠汁,在應(yīng)用層來看蜂大,和HTTP 1.x沒有差別。同時(shí)蝶怔,所有同主機(jī)的通信能夠在一個(gè)TCP連接上完成奶浦。
多路復(fù)用共享連接
基于二進(jìn)制分幀層,HTTP/2.0可以在共享TCP連接的基礎(chǔ)上踢星,同時(shí)發(fā)送請(qǐng)求和響應(yīng)澳叉。HTTP消息被分解為獨(dú)立的幀,而不破壞消息本身的語義沐悦,交錯(cuò)發(fā)送出去成洗,最后在另一端根據(jù)流ID和首部將它們重新組合起來。
對(duì)比HTTP/1.x和HTTP/2.0藏否,假設(shè)不考慮1.x的pipeline機(jī)智瓶殃,雙方四層是一個(gè)TCP連接,客戶端向服務(wù)端發(fā)起三個(gè)圖片請(qǐng)求副签。
- HTTP/1.x發(fā)起的是串行遥椿,即image1返回后才能發(fā)起image2基矮,image2返回后才能發(fā)起image3。
- HTTP/2.0建立一條TCP連接后冠场,并行傳輸3個(gè)數(shù)據(jù)流家浇,客戶端向服務(wù)端錯(cuò)亂發(fā)送stream1-3的一系列DATA幀,與此同時(shí)碴裙,服務(wù)端已經(jīng)在返回stream1的DATA幀
HTTP/2.0成功解決了HTTP/1.X的隊(duì)首阻塞問題(TCP阻塞仍無法解決)蓝谨,同事,也不需要通過pipeline機(jī)智管理多條TCP連接來實(shí)現(xiàn)并行請(qǐng)求與相應(yīng)青团。減少了TCP連接數(shù)對(duì)服務(wù)器性能也有較大提升。
請(qǐng)求優(yōu)先級(jí)
流可以帶有一個(gè)31bit的優(yōu)先級(jí):
- 0:表示最高哦優(yōu)先級(jí)
- 2^31-1:表示最低優(yōu)先級(jí)
客戶端明確指定優(yōu)先級(jí)咖楣,服務(wù)端可以根據(jù)這個(gè)優(yōu)先級(jí)作為依據(jù)交互數(shù)據(jù)督笆,但是在用優(yōu)先級(jí)時(shí)需要注意以下問題: - 服務(wù)端是否支持請(qǐng)求優(yōu)先級(jí)
- 是否會(huì)引起隊(duì)首阻塞問題,比如高優(yōu)先級(jí)的響應(yīng)慢阻塞其他資源請(qǐng)求诱贿。
服務(wù)端推送
HTTP/2.0增加了服務(wù)端推送功能娃肿,服務(wù)端可以根據(jù)客戶端的請(qǐng)求,提前返回多個(gè)響應(yīng)珠十,推送額外的資源給客戶端料扰。
PUSH_PROMISE幀是服務(wù)端向客戶端有意推送的資源信號(hào)。
- 如果客戶端不需要服務(wù)端Push焙蹭,可在SETTINGS幀中設(shè)定服務(wù)端流的值為0晒杈,禁用此功能。
- PUSH_PROMISE幀中只包含預(yù)推送資源的首部孔厉。如果客戶端對(duì)PUSH_PROMISE幀沒有意見拯钻,服務(wù)端在PUSH_PROMISE幀后發(fā)送響應(yīng)的DATA幀開始推送資源。如果客戶端已經(jīng)緩存該資源撰豺,不需要再推送粪般,可以選擇拒絕PUSH_PROMISE幀。
- PUSH_PROMISE必須遵循請(qǐng)求-響應(yīng)原則污桦,只能借著對(duì)請(qǐng)求的響應(yīng)推送資源亩歹。
首部壓縮
HTTP/1.x每一次通信都會(huì)鞋帶首部信息用描述資源屬性。HTTP/2.0在客戶端和服務(wù)端之間使用“首部表”來跟蹤和存儲(chǔ)之前發(fā)的鍵值對(duì)凡橱。首部表在連接中始終存在小作,新增的鍵值對(duì)更新在結(jié)尾們不需要每次通信都攜帶首部。
另外梭纹,HTTP/2.0使用了首部壓縮技術(shù)躲惰,壓縮算法使用HPACHK”涑椋可讓報(bào)頭更緊湊础拨,更快速傳輸氮块。需要注意的是,HTTP/2.0關(guān)注的是首部壓縮诡宗,而我們常用的gzip等是報(bào)文內(nèi)容(body)壓縮滔蝉,二者不沖突。
一個(gè)完整的HTTP/2.0通信過程
客戶端如何知道服務(wù)端是否支持HTTP/2.0塔沃?是否支持對(duì)二進(jìn)制分幀層的編碼和解碼蝠引,所以,使用HTTP/2.0之前蛀柴,必然存在協(xié)議協(xié)商過程螃概。
基于ALPN的協(xié)商過程
支持HTTP/2.0的瀏覽器可以在TLS會(huì)話層自發(fā)完成和服務(wù)器的協(xié)議協(xié)商以確定是否使用HTTP/2.0通信。其原理是TLS 1.2中引入了擴(kuò)展字段鸽疾,允許協(xié)議擴(kuò)展吊洼,其中ALPN協(xié)議用戶客戶端和服務(wù)端的協(xié)議協(xié)商過程。
服務(wù)端使用ALPN制肮,監(jiān)聽443端口默認(rèn)提高HTTP/1.1冒窍,并允許其他協(xié)議協(xié)商,比如SPDY和HTTP/2.0豺鼻。
客戶端可以在TLS握手Client Hello階段表明資深支持HTTP/2.0综液。
服務(wù)端收到后,響應(yīng)Server Hello儒飒,表示自己支持HTTP/2.0
基于HTTP的協(xié)商過程
客戶端使用HTTP也可以開始HTTP/3.0通信谬莹。只不過因?yàn)镠TTP/1.0和HTTP/2.0都使用同一個(gè)端口(80),又沒有服務(wù)端是否是指HTTP/2.0的信息,此時(shí)客戶端只能使用HTTP Upgrade機(jī)制(OKHttp,nghttp2等組件均可實(shí)現(xiàn)桩了,也可以自己編碼完成)通過協(xié)調(diào)確定適當(dāng)?shù)膮f(xié)議届良。
完整的通信過程
TCP連接建立->TLS握手->客戶端向服務(wù)端發(fā)送SETTINGS幀,約定配置->流量控制->客戶端想服務(wù)端發(fā)送HEADER幀->服務(wù)端返回配置->DATA幀傳輸數(shù)據(jù)
HTTP/2.0性能瓶頸
是不是啟用HTTP 2.0后性能必然提升了圣猎?任何事情都不是絕對(duì)的士葫,雖然總體而言性能肯定是能提升的。
我想HTTP 2.0會(huì)帶來新的性能瓶頸送悔。因?yàn)楝F(xiàn)在所有的壓力集中在底層一個(gè)TCP連接之上慢显,TCP很可能就是下一個(gè)性能瓶頸,比如TCP分組的隊(duì)首阻塞問題欠啤,單個(gè)TCP packet丟失導(dǎo)致整個(gè)連接阻塞荚藻,無法逃避,此時(shí)所有消息都會(huì)受到影響洁段。未來应狱,服務(wù)器端針對(duì)HTTP 2.0下的TCP配置優(yōu)化至關(guān)重要,有機(jī)會(huì)我們?cè)俑M(jìn)詳述祠丝。
參考文獻(xiàn)
《圖解HTTP》
《HTTP 2.0 原理詳細(xì)分析》