三萬長文50+趣圖帶你領悟web編程的內功心法:一文帶你深入解讀HTTP的發展史


看到題目,大家是不是認為根據上一篇(兩萬字長文50+張趣圖帶你領悟網絡編程的內功心法)一樣,其實不然,我們上一邊介紹的是網絡編程的基本功,有了這些基本功之后,我們就可以在此之上構建更加接近實際應用的web程序了。為了快速展示他們的層次關系,我用幾本書疊了起來進行說明,順便給大家推薦這幾本基本算是這些領域比較權威的書籍。如下圖,由下往上看:

image-20200913190523972

  • TCP/IP構成了網絡編程的基礎設施;
  • Socket套接字編程為應用層提供了訪問TCP/IP協議棧的接口;
  • 在應用層上面,指定了面向Web編程的HTTP協議;
  • Tomcat是實現HTTP協議的一個應用服務器。

兩萬字長文50+張趣圖帶你領悟網絡編程的內功心法 一文中,我們詳細介紹了TCP/IP協議,從物理層一直講到了應用層。在應用層可以利用TCP/IP底層的能力,實現豐富的功能,而本文,我們就重點講解構建在應用層上的協議:HTTP協議。

首先,我們來思考一個問題,HTTP是怎么來的,為什么要創造HTTP,HTTP接下來會怎么發展呢?這就得聊聊HTTP的發展演變史了。

閱讀本文的同時,我們可以看到整個HTTP的發展演變史,可以發現,假設規范是一個小伙子,一般來說,一個優秀的小伙子從來不是出生之后就是優秀的,而是隨着業務場景,技術挑戰的產生,不斷的被拉去勞改,學習,在憂患中蛻變進化。所以現在所謂的標准、成熟的技術,未必符合所有的場景,是技術的挑戰與創新促成了新事務的發展。

(前方高能預警:此處有篇高考高分作文💯...)如果Google只滿足於HTTP/1.1,就不會推出SPDY促進HTTP/2的誕生了;如果Google只滿足於SPDY,就不會推出QUIC促進HTTP/3的誕生了;如果快手只滿足於HTTP/1.1,就不會自己實現一套kQUIC了;如果我只滿足於通過HttpClient發起HTTP調用,就不會寫這篇文章了。

還記得那個學術風濃厚的OSI網絡模型嗎,最終是被TCP/IP給蓋過了風頭。深入應用場景,深入業務,挖掘痛點,探索折騰起來吧。哦對了,最重要的一點:計算機基礎知識得打牢固。

1、HTTP發展演變史

話不多少,我直接畫了一個圖,總結一下HTTP的演變史,一個從誕生之日開始就不斷被勞改的小伙子,一路被互聯網巨頭和互聯網標准化組織IETF逐漸帶上正軌的心酸歷史,它還有很長一段路需要走:

image-20200913211955666

image-20200816161701982

1.1、時代背景

在HTTP協議誕生以前,都有哪些事情的發生,為其做好了鋪墊呢?下面來看看。

image-20200816161641063

接下來,我會請出我們的機器人為我們總結每個小節的技術,格式如下:

image-20200816182046028

每個版本的協議都會有很多特性,這個章節會把相關特性或者技術點描述出來,但是在發展演變史這章節不會細講,我們后面會有專門章節為你揭秘HTTP技術點的詳細實現原理。

所以,本章節主要是為您梳理HTTP的發展演變史,知道技術的來龍去脈,以及接下來的發展趨勢。

1.1.1、ARPANET

ARPANET(Advanced Research Projects Agency Network)是第一個具有分布式控制的廣域分組交換網絡,該網絡由美國國防部高級研究計划局建立。

為了實現對遠程計算機的訪問,美國互聯網先驅 Bob Taylor 在1966年啟動了ARPANET項目,1969年連接了第一台計算機,在1970年實現了網絡控制程序。

關於為何要搞這樣的技術,據ARPA的總監Charles Herzfeld說:因為當時美國直郵數量有限的大型的研究計算機,而許多應該使用這些計算機的研究人員由於地理空間問題導致不能很好使用起來,這使他們感到很挫敗,所以就提出了這個研究計划。當然也有傳言是處於軍事目的,實現對核力量的控制,改善軍事戰術和管理決策。但不管怎樣,網絡世界從此往前邁進了一大步。

image-20200816184337629

1.1.2、TCP/IP

在70年代的時候,基於ARPA網絡的發展,研究人員指定了傳輸控制方案,最終演變成了一個協議,通過該協議可以將多個單獨的網絡合成一個網絡,這個協議也就是TCP/IP。

在1983年UNIX操作系統BSD誕生了,其內核就包含了網絡編程套接字的設計和實現,TCP/IP就這么被BSD帶起來了,最終逐漸成為了事實的標准。

可以說UNIX套接字聯網API就是網絡編程的一個源頭了,所以大學老師教網絡編程的時候大概率會推薦這本書:《UNIX網絡編程 卷1:套接字聯網API》,當時我們老師也推薦了這本書,雖然當時大概率不會細看,但是遲早會用到的。

image-20200816184508075

1.1.3、OSI參考模型

兩萬字長文50+張趣圖帶你領悟網絡編程的內功心法 一文我們也提到了,為了制定一個統一的計算機網絡體系,國際標准化組織ISO提出了一個試圖使各種計算機可以在世界范圍內互聯成網的標准框架:OSI/RM(Open System Interconnection Reference Model 開放系統互連基本參考模型)。

不過嘛,這個標准是1984年發布的,此時TCP/IP已占據大半江山,逐漸成為了事實的標准,而且OSI更加學術,上一篇文章我們也提到了OSI的一些缺點,導致其不能取代TCP/IP,TCP/IP則是在實踐中得到了驗證。

1.1.4、World Wide Web

好了,萬事具備,我們離HTTP的誕生越來越接近了。

在1989年,英國工程師兼計算機科學家 Timothy Berners-Lee 在1989年發明了World Wide Web萬維網,萬維網是信息時代發展的核心。他開發了三種基礎技術:

  • URI:統一資源標識符;
  • HTML:超文本標記語言;
  • HTTP:超文本傳輸協議;

是什么促成了 Timothy Berners-Lee 發明萬維網呢?在CERN工作的時候,他對查找存儲在不同計算機上的信息所帶來的低效率和困難感到沮喪。於是,他想CERN管理層提交了一份備忘錄:《信息管理:一項提案》。逐漸促成了可以在文檔中通過單擊鼠標跳轉到其他引用的文檔的系統的實現,這種呈現形式的文檔被稱為超文本

HTTP誕生了。

image-20200816184431658

1.2、HTTP/0.9

1991年,是一個單純的年代,網上只有文字,看不了圖,看不了片。在如此單純的環境下,Timothy Berners-Lee設計了HTTP協議的0.9版本,為啥不給多個0.1湊個整呢,因為跟我們現在用的HTTP1.1+協議比起來實在是簡單多了:

  • 基於客戶端服務端的請求響應協議;
  • 沒有首部;
  • 沒有狀態碼;
  • 只支持純文本,其設計目標是獲取HTML;
  • 只支持GET方法;
  • 每次請求都建立新的TCP連接;

但是這也是滿足那個純真年代的需求了。保持簡單,避免過度設計也好,為后續擴展留了個口子。

image-20200816184603785

1.2.1、報文示例

HTTP/0.9協議下通過瀏覽器訪問:https://www.itzhai.com/hello-world.html

在建立了TCP連接之后,最終瀏覽器會發送報文如下:

GET /hello-world.html

GET后面為什么是資源路徑,而不是URL呢?

因為瀏覽器首先是拿到了URL對應的IP地址,然后建立TCP連接,一旦連接到服務器,就不需要協議,服務器,和端口號了。第二節我們會抓包演示。

響應也非常簡單,僅僅由HTML文件本身組成:

<html>
  <body>
    welcome to itzhai (www.itzhai.com), wechat account: itread.
  </body>
</html>

可以發現:

  • 沒有HTTP首部,也就意味着只能傳輸HTML文件;
  • 沒有狀態碼:出現問題的時候,只能發送一個特定的HTML文件,其中包含問題的描述,以供人們解讀錯誤信息。

1.3、HTTP/1.0

人們的欲望是那么的沒有止境呀,后來又想在網上看小圖片,又想聽音樂,不單單只是看文字了,還想自己寫段子到網上。這么多需求來了,只能升級HTTP協議了。在1996年5月,HTTP工作組發布了RFC 1945[1],在該文檔中記錄了許多HTTP/1.0實現的通用方法,於是HTTP/1.0就誕生了。

HTTP/1.0跟我現在用的HTTP/1.1比接近了,加了如下概念:

  • 增加了首部:

    • Allow
    • Authorization
    • Content-Encoding
    • Content-Length
    • Content-Type
    • Date
    • Expires
    • From
  • 增加了16個響應狀態碼;

  • 引入了重定向;

  • 內容編碼(壓縮):

    • content-coding = "x-gzip" | "x-compress" | token
      
  • 更多的請求方法:GET,HEAD,POST;

  • 傳輸數據不限於文本;

更詳細的內容,參考RFC 1945[1:1]

但是,HTTP/1.0並不是一個正是規范或Interger標准,只是一個已有實踐的參考文檔,沒有約束力,對當時的互聯網來說沒有太大的推進作用。

另外,HTTP/1.0也是有很多瑕疵的,比如不能讓多個請求共用一個TCP連接,缺少強制的Host首部,並且緩存比較控制比較粗糙。

image-20200816184132917

如何復用TCP連接?

有些瀏覽器在請求的時候,會使用一個非標准的Connection字段:

Connection: keep-alive

這個表示客戶端端要求服務器不要關閉TCP連接,以便其他請求可以復用,服務器同樣的回應這個字段。

1.3.1、報文示例

HTTP/1.0協議下通過瀏覽器訪問:https://www.itzhai.com/hello-world2.html

請求報文如下所示:

GET /hello-world2.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
Accept: */*

響應報文如下所示:

200 OK
Date: Tue, 15 Nov 1996 08:00:00 GMT
Server: Apache 0.84
Content-Type: text/html

<html>
  <body>
    welcome to itzhai (www.itzhai.com), wechat account: itread.<br/>
    <img src="https://www.itzhai.com/resources/images/itzhai_qrcode.jpeg" width="100px">
  </body>
</html>

由於瀏覽器拿到響應的HTML之后,解析到里面還有一個img圖片請求,於是又發起了第二個連接獲取圖片:

GET /resources/images/itzhai_qrcode.jpeg HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

響應報文如下所示:

200 OK
Date: Tue, 15 Nov 1996 08:00:01 GMT
Server: Apache 0.84
Content-Type: image/jpeg

(image content)

1.4、HTTP/1.1

將HTTP轉變為正式的IETF Internet標准的工作與圍繞HTTP/1.0文檔編制工作並行進行。

有道是,有競爭才會有進步,微軟在1995年推出的Windows系統中發布了IE瀏覽器,與當時的瀏覽器霸主Netscape瀏覽器展開對抗,IE逐步占有了更多的市場,直到1998年Netscape被AOL收購后,IE的市場還在不斷攀升,在兩大瀏覽器互相廝殺期間,HTTP/1.1誕生了。

image-20200816191000557

在1997年1月,發布了HTTP/1.1的第一個正式標准 RFC2068[2]。然后,在兩年半之后的1999年6月,許多改進和更新被納入該標准,並以 RFC 2616[3]的形式發布。

HTTP/1.1有如下特性:

  • 新增了POTIONS、PUT、DELETE、TRACE、CONNECT等新方法;

  • 強化了緩存管理和控制;

  • 支持維持持久連接,支持通知服務器棄用連接;也就是說TCP連接默認不關閉,可以被多個請求復用,不用聲明Connection: keep-alive

  • 請求HTML文件的時候要求攜帶編碼、字符集、cookie元數據等信息;

  • 支持原始HTML請求的分塊響應,利於傳輸大文件;

就這樣,一個最穩定版本的HTTP協議誕生了,直到現在,仍然有很多網站在使用HTTP/1.1協議。

image-20200816183918954

在HTTP/1.1期間,涌現了很多互聯網企業,如,Google,騰訊,百度,阿里,淘寶,美團頭條等。

image-20200816191319930

1.4.1、報文示例

請求報文:

GET /hello-world2.html HTTP/1.1
Host: www.itzhai.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
If-None-Match: "9a3bee90-q1"
If-Modified-Since: Tue, 18 Aug 2020 15:06:33 GMT

響應報文:

HTTP/1.1 200 OK
Date: Tue, 18 Aug 2020 15:30:57 GMT
Last-Modified: Tue, 18 Aug 2020 15:06:33 GMT
Content-Type: text/html
Content-Length: 192
ETag: "5f3bee79-c0"
Accept-Ranges: bytes

<html>
  <body>
    welcome to itzhai (www.itzhai.com), wechat account: itread.<br/>
    <img src="https://www.itzhai.com/resources/images/itzhai_qrcode.jpeg" width="200px">
  </body>
</html>

HTTP/1.1具體特性說明我們第二節會講到。

本文首次發表於: HTTP發表演變史 以及公眾號 Java架構雜談,未經許可,不得轉載。

1.5、HTTP/2

當然,HTTP/1.1的問題也是很多的,主要是連接緩慢,服務器只能按順序響應,如果某個請求花了很長時間,就會出現請求隊頭阻塞,從而影響其他請求。

這個時期出現了很多各式的前端優化小技巧,當年搞過一段時間前端,也對這些技術略知一二,如:

  • 為了增加並發請求,做域名拆分;
  • CSS、JS等資源內聯到HTML中,或者進行資源合並;
  • 生成精靈圖,一次性傳輸所有小圖標;
  • 資源預取...

最終,為了推進從協議上進行優化,Google跳出來了,推出了SPDY協議。

1.5.1、SPDY

為啥Google敢推出這樣的協議呢,主要還是因為在2008年誕生的Chrome瀏覽器迅速占據了市場,擁有了大部分用戶,挾天子以令諸侯,嘗試推廣新技術是水到渠成的事情。

image-20200816191558976

SPDY是Google開發,用於傳輸Web內容的協議,SPDY協議減少了網頁加載延遲,並且提高了We標的安全性。

SPDY主要通過幀和首部壓縮、多路復用和優先級屬性降低等待時間。

SPDY誕生之后,很快被整合進Chrome和Firefox,最終被所有主流瀏覽器所采用,另外服務器和網絡代理也對SPDY提供了必要的支持。

SPDY的核心人員后來都參與到了HTTP/2的開發,在2015年2月,Google宣布最終批准HTTP/2標准之后,也就不再繼續支持SPDY協議了,並且最終在Google Chrome 51中刪除了SPDY的支持。

1.5.2、HTTP/2

HTTP/2又解決了HTTP/1.1面臨的大部分問題,主要有如下功能:

  • 使用虛擬的流傳輸消息,解決了HTTP一個連接中應用層的隊頭阻塞的問題;
  • 使用了二進制協議,不再是純文本,避免文本歧義,縮小了請求體積;
  • 實現了多路復用,提高了連接的利用率,在擁塞控制方面有了更好的能力提升;
  • 使用HPACK首部壓縮方案壓縮頭部信息,大大節約了帶寬;
  • 增強了安全性,使用HTTP/2,要求必須至少用TLS1.2;
  • 允許服務器主動向客戶端推送數據;

image-20200816184010614

1.6、HTTP/3

HTTP/2還在草案的時候,Google又發現新的問題了,那就是由於HTTP/2依賴於TCP,TCP有什么問題,那么HTTP/2就會存在什么問題。最主要的問題還是隊頭阻塞問題:隊頭阻塞問題在應用層解決了,但是在TCP協議層並沒有解決:

  • 上一篇文章我們提到過TCP在丟包的時候會進行重傳,前面有一個包沒有接收到,就只能把后面的包先放到緩沖區里面,應用層實際上是無法取數據的。也就是說HTTP / 2的多路復用的並行性對於TCP的丟失恢復機制不管用,因此丟失或者重新排序的數據報都會導致所有活動事務陷入停頓。

為了解決以上問題,於是Google發明了gQUIC(Quick UDP Internet Connection)協議。

1.6.1、QUIC

QUIC是最初由Google開發的一種傳輸層網絡協議,在QUIC協議中,傳輸層用UDP替換掉了TCP,並在用戶空間實現了一套擁塞控制算法,從而避免了TCP的隊頭阻塞問題。

在UDP之上,QUIC實現了連接管理、擁塞窗口、流量控制等。

后來IETF HTTP和QUIC工作組主席Mark Nottingham提出了正式請求,將HTTP-over-QUIC重命名為HTTP/3。

1.6.2、HTTP/3

HTTP / 3使用與HTTP/1.1和HTTP/2相同的語義(相同的操作,例如GET和POST)和相同的響應代碼(例如200或404),但是使用QUIC傳輸協議協議,以及采用類似於HTTP/2的內部成幀層提供HTTP語義的傳輸。

image-20200816184054126

HTTP/3進展如何?

截止到2020年8月,HTTP/3協議已經成為Internet草案,並且具有多種實現方案,前1000萬個網站中有6.7%支持HTTP / 3。在瀏覽器方面,Firefox和Chrome穩定版本都支持HTTP/3,但是默認情況下是禁用的,Safari 14將默認啟用HTTP/3。

想進一步了解,可以閱讀最新的發布於2020年8月14日的HTTP/3草案:Hypertext Transfer Protocol Version 3 (HTTP/3)[4]


目前我們使用最廣發的還是HTTP/1.1,接下來我就基於HTTP/1.1來介紹下HTTP協議。

接下來,由於篇幅所限,為了給大家呈現更好的閱讀體驗,我把后續的內容分為以下章節,深入細節更精彩,歡迎大家繼續閱讀:

file


這篇文章的內容就介紹到這里,能夠閱讀到這里的朋友真的是很有耐心,為你點個贊。

本文為arthinking基於相關技術資料和官方文檔撰寫而成,確保內容的准確性,如果你發現了有何錯漏之處,煩請高抬貴手幫忙指正,萬分感激。

如果您覺得讀完本文有所收獲的話,可以關注我的賬號,或者點贊吧,碼字不易,您的支持就是我寫作的最大動力,再次感謝!

為了把相關系列文章收集起來,方便后續查閱,這里我創建了一個Github倉庫,把發布的文章按照分類收集起來了,感興趣的朋友可以Star跟進:

https://github.com/arthinking/java-tech-stack

java-tech-stack-info

關注我的博客IT宅(itzhai.com)或者公眾號Java架構雜談,及時獲取最新的文章。我將持續更新后端相關技術,涉及JVM、Java基礎、架構設計、網絡編程、數據結構、數據庫、算法、並發編程、分布式系統等相關內容。

References

  • 謝希仁. 計算機網絡(第6版). 電子工業出版社.
  • TCP/IP詳解 卷1:協議(原書第2版). 機械工業出版社.
  • UNIX網絡編程 卷1:套接字聯網API. 人民郵電出版社
  • HTTP權威指南. 人民郵電出版社
  • HTTP/2基礎教程. 人民郵電出版社
  • 劉超. 趣談網絡協議. 極客時間
  • 羅劍鋒. 透視HTTP協議. 即可時間

本文同步發表於我的博客IT宅(itzhai.com)和公眾號(Java架構雜談)

作者:arthinking | 公眾號:Java架構雜談

博客鏈接:https://www.itzhai.com/articles/comprehend-the-underlying-principles-of-web-programming.html

版權聲明: 版權歸作者所有,未經許可不得轉載,侵權必究!聯系作者請加公眾號。


  1. Hypertext Transfer Protocol -- HTTP/1.0 RFC 1945. Retrieved from https://datatracker.ietf.org/doc/rfc1945/ ↩︎ ↩︎

  2. HypertextTransferProtocol--HTTP/1.1 2068. Retrieved from https://tools.ietf.org/html/rfc2068 ↩︎

  3. Hypertext Transfer Protocol -- HTTP/1.1 2616. Retrieved from https://tools.ietf.org/html/rfc2616 ↩︎

  4. Hypertext Transfer Protocol Version 3 (HTTP/3). Retrieved from https://quicwg.org/base-drafts/draft-ietf-quic-http.html ↩︎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM