HTTP协议之:HTTP/1.1和HTTP/2
文章目錄
- 簡(jiǎn)介
- HTTP/1.1
- HTTP/2
- 傳輸模式對(duì)比
- 流優(yōu)先級(jí)
- 緩沖區(qū)溢出處理
- 預(yù)測(cè)資源請(qǐng)求
- 壓縮
- 總結(jié)
簡(jiǎn)介
HTTP的全稱是Hypertext Transfer Protocol,是在1989年World Wide Web發(fā)展起來(lái)之后出現(xiàn)的標(biāo)準(zhǔn)協(xié)議,用來(lái)在WWW上傳輸數(shù)據(jù)。HTTP/1.1是1997年在原始的HTTP協(xié)議基礎(chǔ)上進(jìn)行的補(bǔ)充和優(yōu)化。
到了2015年,為了適應(yīng)快速發(fā)送的web應(yīng)用和現(xiàn)代瀏覽器的需求,發(fā)展出了新的HTTP/2協(xié)議,主要在手機(jī)瀏覽器、延時(shí)處理、圖像處理和視頻處理方面進(jìn)行了優(yōu)化。
基本上所有的現(xiàn)代瀏覽器都支持HTTP/2協(xié)議了,但是還有很多應(yīng)用程序使用的是老的HTTP/1.1協(xié)議,本文將會(huì)介紹HTTP/1.1和HTTP/2的不同之處。
HTTP/1.1
HTTP 1.0 是由Timothy Berners-Lee在1989年作為World Wide Web的標(biāo)準(zhǔn)協(xié)議發(fā)布的。通常使用HTTP方法如:GET或者POST,以TEXT文本的形式在客戶端和服務(wù)器端進(jìn)行消息傳輸。
我們可以使用post man很方便的進(jìn)行HTTP請(qǐng)求,如下所示:
GET /index.html HTTP/1.1 Host: www.flydean.com客戶端通過(guò)GET請(qǐng)求,請(qǐng)求服務(wù)器端的/index.html頁(yè)面,使用的協(xié)議是HTTP/1.1,服務(wù)器端收到該請(qǐng)求之后,會(huì)將相應(yīng)以文本的形式返回給客戶端。
HTTP協(xié)議是對(duì)底層的TCP/IP協(xié)議的封裝,因?yàn)槲覀儾恍枰唤泳唧w的報(bào)文拆分和封裝的底層細(xì)節(jié),只需要關(guān)注于具體的業(yè)務(wù)邏輯即可,非常的方便。
HTTP/2
HTTP/2是從SPDY協(xié)議發(fā)展出來(lái)的,它的發(fā)起者是Google,最初是為了在web交互中引入壓縮、多路復(fù)用等新的技術(shù),最終在2015年被作為HTTP/2協(xié)議的一部分。
之前我們講到HTTP/1.1是以文本的形式進(jìn)行傳輸?shù)?#xff0c;這樣的缺點(diǎn)就是數(shù)據(jù)占用的空間比較大,相較于HTTP/1.1來(lái)說(shuō)HTTP/2使用的是二進(jìn)制進(jìn)行傳輸?shù)?#xff0c;使用二進(jìn)制對(duì)消息進(jìn)行封裝,同時(shí)保留了HTTP的語(yǔ)義,比如方法,頭等。
這種二進(jìn)制的封裝對(duì)應(yīng)用層是無(wú)感知的,對(duì)于應(yīng)用來(lái)說(shuō),還是按照常用的方法來(lái)創(chuàng)建HTTP請(qǐng)求,將其封裝成二進(jìn)制的工作是由HTTP/2來(lái)完成的。
傳輸模式對(duì)比
在HTTP1.0中,每當(dāng)客戶端向服務(wù)器端請(qǐng)求頁(yè)面的時(shí)候,往往返回的不是一個(gè)完整的頁(yè)面,而是這個(gè)頁(yè)面還需要的額外的資源鏈接信息,因?yàn)橥暾捻?yè)面需要所有的資源都下載完畢之后才能展示,所以在HTTP1.0中,客戶端需要中斷當(dāng)前的連接,然后重新建立新的連接去請(qǐng)求資源。這會(huì)額外耗費(fèi)多余的資源和時(shí)間。
在HTTP1.1中,引入了持久連接和管道的概念,這樣不用每次請(qǐng)求都去重新開(kāi)啟和新建連接,HTTP默認(rèn)底層的TCP連接是open的,除非手動(dòng)告訴它要去關(guān)閉。在這種情況下,客戶端可以使用同一個(gè)連接去和server進(jìn)行交互,從而極大的提升HTTP的效率。
雖然在HTTP1.1中可以使用同一個(gè)連接進(jìn)行數(shù)據(jù)傳輸了,但是對(duì)于這個(gè)連接來(lái)說(shuō),其中的請(qǐng)求是一一響應(yīng)的,他們是有順序的。如果最前面的請(qǐng)求被阻塞了,后面的請(qǐng)求也得不到響應(yīng)。這種情況被稱為head-of-line (HOL) blocking。
為了解決這個(gè)問(wèn)題,可以在client和server端建立多個(gè)連接,這樣就可以利用多個(gè)connection并行進(jìn)行數(shù)據(jù)的傳輸,從而提升傳輸效率。
但是這樣的缺點(diǎn)就是新建連接會(huì)消耗太多的資源,并且客戶端和服務(wù)器端的連接個(gè)數(shù)也是有限的。
所以HTTP/2出現(xiàn)了。
在 HTTP/2 中,數(shù)據(jù)以二進(jìn)制的的格式進(jìn)行傳輸,其本身是將原始請(qǐng)求的切分成為更小的信息包,從而大大增加了數(shù)據(jù)傳輸?shù)撵`活性。
HTTP1.1需要建立多個(gè)TCP連接從而解決并行傳輸?shù)膯?wèn)題,但是在HTTP/2 中只需要建立一個(gè)連接就夠了。在這個(gè)連接中可以傳輸多個(gè)數(shù)據(jù)流,每個(gè)數(shù)據(jù)流中又包含多個(gè)message包,每個(gè)message又被切分為多個(gè)數(shù)據(jù)frame。
這些數(shù)據(jù)frame可以在傳輸期間交換位置,然后在接收的另一端重新組裝。 交錯(cuò)的請(qǐng)求和響應(yīng)可以并行運(yùn)行,從而不會(huì)阻塞它們背后的消息,這個(gè)過(guò)程被稱為多路復(fù)用。 多路復(fù)用的機(jī)制使得一個(gè)消息不用等待另外一個(gè)消息發(fā)送完成,從而解決了HTTP/1.1 中的隊(duì)頭阻塞問(wèn)題。 這也意味著服務(wù)器和客戶端可以發(fā)送并發(fā)請(qǐng)求和響應(yīng),從而實(shí)現(xiàn)更好的控制和更有效的連接管理。
多路復(fù)用雖然構(gòu)建了多個(gè)消息流,但是只占用了一個(gè)TCP連接,從而減少整個(gè)網(wǎng)絡(luò)的內(nèi)存和處理占用空間,得到更好的網(wǎng)絡(luò)和帶寬利用率,從而降低整體運(yùn)營(yíng)成本。
單個(gè)TCP連接還提高了HTTPS協(xié)議的性能,因?yàn)榭蛻舳撕头?wù)器可以為多個(gè)請(qǐng)求/響應(yīng)重用相同的安全會(huì)話。 在HTTPS中,在TLS或SSL握手期間,雙方在整個(gè)會(huì)話期間使用單個(gè)密鑰。 如果連接中斷從新開(kāi)始新的會(huì)話,則需要新生成的密鑰進(jìn)行進(jìn)一步通信。 因此,維護(hù)單個(gè)連接可以大大減少HTTPS所需的資源。
請(qǐng)注意,盡管HTTP/2規(guī)范并未強(qiáng)制要求使用TLS,但許多主要瀏覽器僅支持帶有HTTPS的HTTP/2。
流優(yōu)先級(jí)
雖然HTTP/2解決了多個(gè)數(shù)據(jù)frame通常傳輸?shù)膯?wèn)題,但是對(duì)于同一個(gè)資源來(lái)說(shuō),必須要等到的所有的數(shù)據(jù)frame都接受完畢之后才能展示,如果我們想優(yōu)先展示某個(gè)資源該怎么做呢?
HTTP/2提供了流優(yōu)先級(jí)的解決方案。
在客戶端向服務(wù)器端發(fā)送消息的時(shí)候,消息會(huì)以流的形式在連接中傳輸,這些流可以分配1到256之間的權(quán)重來(lái)確定其請(qǐng)求的響應(yīng)的優(yōu)先級(jí)。 數(shù)字越大表示優(yōu)先級(jí)越高。 除此之外,客戶端還通過(guò)指定它所依賴的流的ID來(lái)說(shuō)明每個(gè)流對(duì)另一個(gè)流的依賴關(guān)系。 如果省略父標(biāo)識(shí)符,則認(rèn)為該流依賴于根流。
服務(wù)器會(huì)使用流中的ID構(gòu)建一個(gè)依賴樹(shù),從而確定其相應(yīng)的順序。
應(yīng)用程序的開(kāi)發(fā)人員可以根據(jù)需要自行設(shè)置請(qǐng)求的優(yōu)先級(jí),比如在網(wǎng)頁(yè)中提供低分辨率的縮略圖的同時(shí)提供低優(yōu)先級(jí)的高分辨率的圖像。通過(guò)為資源分配不同的優(yōu)先級(jí),開(kāi)發(fā)人員能夠更好地控制網(wǎng)頁(yè)渲染。
緩沖區(qū)溢出處理
不管是哪種協(xié)議,客戶端和服務(wù)器端在接收數(shù)據(jù)的時(shí)候都有一個(gè)緩沖區(qū)來(lái)臨時(shí)存儲(chǔ)暫時(shí)處理不了的數(shù)據(jù),但是緩沖區(qū)的大小是有限制的,所以有可能會(huì)出現(xiàn)緩沖區(qū)溢出的情況,比如客戶端向服務(wù)器端上傳一個(gè)大的圖片,就有可能導(dǎo)致服務(wù)器端的緩沖區(qū)溢出,從而導(dǎo)致一些額外的數(shù)據(jù)包丟失。
為了避免緩沖區(qū)溢出,各個(gè)HTTP協(xié)議都提供了一定的解決辦法。
在HTTP1.1中,流量的控制依賴的是底層TCP協(xié)議,在客戶端和服務(wù)器端建立連接的時(shí)候,會(huì)使用系統(tǒng)默認(rèn)的設(shè)置來(lái)建立緩沖區(qū)。在數(shù)據(jù)進(jìn)行通信的時(shí)候,會(huì)告訴對(duì)方它的接收窗口的大小,這個(gè)接收窗口就是緩沖區(qū)中剩余的可用空間。如果接收窗口大小為零,則說(shuō)明接收方緩沖區(qū)已滿,則發(fā)送方將不再發(fā)送數(shù)據(jù),直到客戶端清除其內(nèi)部緩沖區(qū),然后請(qǐng)求恢復(fù)數(shù)據(jù)傳輸。
因?yàn)镠TTP1.1使用多個(gè)TCP連接,多以可以對(duì)每一個(gè)TCP連接進(jìn)行單獨(dú)的流量控制。但是HTTP2使用的是多路復(fù)用的模式,所以它的流量控制方式和HTTP1.1是不同的。
HTTP2是通過(guò)客戶端和服務(wù)器端的應(yīng)用中進(jìn)行緩沖區(qū)大小消息的傳輸,是通過(guò)在應(yīng)用層層面控制數(shù)據(jù)流,所以各個(gè)應(yīng)用端可以自行控制流量的大小,從而實(shí)現(xiàn)更高的連接效率。
HTTP/2提供了更詳細(xì)的控制級(jí)別,從而開(kāi)啟了更大優(yōu)化的可能性。
預(yù)測(cè)資源請(qǐng)求
在一個(gè)典型的web應(yīng)用中,當(dāng)客戶端發(fā)動(dòng)一個(gè)GET請(qǐng)求到服務(wù)器端的時(shí)候,通常客戶端會(huì)發(fā)現(xiàn)所以需要的不止一個(gè)資源,還可能包含了CSS或者其他JS等資源。但是客戶端只有在首次獲取到服務(wù)器端的響應(yīng)時(shí)候才能真正確認(rèn)到底需要哪些資源。然后需要額外請(qǐng)求這些資源以完成整個(gè)請(qǐng)求。但是這些額外的請(qǐng)求最終會(huì)增加連接加載時(shí)間。
那么有沒(méi)有可能服務(wù)器在客戶端請(qǐng)求之前將資源發(fā)送給客戶端呢?我們看下HTTP1.1和HTTP2是怎么做的。
在HTTP1.1中,主要使用的資源內(nèi)聯(lián)的方式,比如將客戶端所需要的CSS或者JS資源包含在服務(wù)器最初發(fā)送的HTML文檔中,也就是做內(nèi)聯(lián)操作,從而減少客戶端必須發(fā)送的請(qǐng)求總數(shù)。
但是這樣的解決方案也有問(wèn)題。因?yàn)橐话銇?lái)說(shuō)資源內(nèi)聯(lián)一般是針對(duì)較小的資源來(lái)說(shuō)的,如果資源文件太大的話,就會(huì)大大的增加HTML文件的大小,從而抵消減少連接提升的速度優(yōu)勢(shì)。
另外如果資源被放在HTML中,那么客戶端就沒(méi)有可能對(duì)這些資源進(jìn)行緩存,從而影響整體的效率。
在HTTP/2中使用的是服務(wù)器推送。因?yàn)镠TTP/2在同一個(gè)連接中可以發(fā)送多個(gè)stream,所以服務(wù)器可以將資源與請(qǐng)求的HTML頁(yè)面一起發(fā)送到客戶端,在客戶端請(qǐng)求之前提供資源。 這個(gè)過(guò)程被稱為服務(wù)器推送。
這樣就可以在不用新開(kāi)連接的同時(shí),實(shí)現(xiàn)HTML文檔和資源的分離和同時(shí)推送。
但是在HTTP/2中,服務(wù)器推送是由應(yīng)用程序來(lái)控制的,所以控制起來(lái)會(huì)比較復(fù)雜。我們會(huì)在后續(xù)的文章中詳細(xì)講解HTTP/2的服務(wù)器推送。
壓縮
通常為了減少數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸,我們需要對(duì)數(shù)據(jù)進(jìn)行壓縮,接下來(lái)我們看一下在HTTP1.1和HTTP2中都是怎么做的。
在HTTP1.1中,通常使用gzip對(duì)HTTP中的消息進(jìn)行壓縮,主要是針對(duì)CSS文件和javascript文件,但是HTTP的消息頭還是由純文本來(lái)發(fā)送的,另外由于cookie的使用,導(dǎo)致HTTP消息頭的大小會(huì)越來(lái)越大,從而對(duì)程序的性能造成一定的影響。
在HTTP/2中,使用的算法是HPACK算法,同時(shí)可以對(duì)HTTP頭和數(shù)據(jù)分別進(jìn)行壓縮,從而大大減少其大小。
總結(jié)
HTTP/2在HTTP1.1的基礎(chǔ)上進(jìn)行了更加細(xì)粒度的優(yōu)化控制,并提供了包括多路復(fù)用、流優(yōu)先級(jí)、流量控制、服務(wù)器推送和壓縮等高級(jí)特性。非常強(qiáng)大。希望大家能夠喜歡。
本文已收錄于 http://www.flydean.com/02-http1-1-vs-http2/
最通俗的解讀,最深刻的干貨,最簡(jiǎn)潔的教程,眾多你不知道的小技巧等你來(lái)發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號(hào):「程序那些事」,懂技術(shù),更懂你!
總結(jié)
以上是生活随笔為你收集整理的HTTP协议之:HTTP/1.1和HTTP/2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: netty系列之:在netty中使用pr
- 下一篇: netty系列之:轻轻松松搭个支持中文的