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

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

image-20200913190523972

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

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

首先,咱們來思考一個問題,HTTP是怎麼來的,爲何要創造HTTP,HTTP接下來會怎麼發展呢?這就得聊聊HTTP的發展演變史了。java

閱讀本文的同時,咱們能夠看到整個HTTP的發展演變史,能夠發現,假設規範是一個小夥子,通常來講,一個優秀的小夥子歷來不是出生以後就是優秀的,而是隨着業務場景,技術挑戰的產生,不斷的被拉去勞改,學習,在憂患中蛻變進化。因此如今所謂的標準、成熟的技術,未必符合全部的場景,是技術的挑戰與創新促成了新事務的發展。git

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

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

一、HTTP發展演變史

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

image-20200913211955666

image-20200816161701982

1.一、時代背景

在HTTP協議誕生之前,都有哪些事情的發生,爲其作好了鋪墊呢?下面來看看。數據庫

image-20200816161641063

接下來,我會請出咱們的機器人爲咱們總結每一個小節的技術,格式以下:編程

image-20200816182046028

每一個版本的協議都會有不少特性,這個章節會把相關特性或者技術點描述出來,可是在發展演變史這章節不會細講,咱們後面會有專門章節爲你揭祕HTTP技術點的詳細實現原理。後端

因此,本章節主要是爲您梳理HTTP的發展演變史,知道技術的前因後果,以及接下來的發展趨勢。

1.1.一、ARPANET

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

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

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

image-20200816184337629

1.1.二、TCP/IP

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

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

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

image-20200816184508075

1.1.三、OSI參考模型

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

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

1.1.四、World Wide Web

好了,萬事具有,咱們離HTTP的誕生愈來愈接近了。

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

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

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

HTTP誕生了。

image-20200816184431658

1.二、HTTP/0.9

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

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

可是這也是知足那個純真年代的需求了。保持簡單,避免過分設計也好,爲後續擴展留了個口子。

image-20200816184603785

1.2.一、報文示例

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.三、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.一、報文示例

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.四、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.一、報文示例

請求報文:

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.五、HTTP/2

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

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

  • 爲了增長併發請求,作域名拆分;
  • CSS、JS等資源內聯到HTML中,或者進行資源合併;
  • 生成精靈圖,一次性傳輸全部小圖標;
  • 資源預取...

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

1.5.一、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.二、HTTP/2

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

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

image-20200816184010614

1.六、HTTP/3

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

  • 上一篇文章咱們提到過TCP在丟包的時候會進行重傳,前面有一個包沒有接收到,就只能把後面的包先放到緩衝區裏面,應用層其實是沒法取數據的。也就是說HTTP / 2的多路複用的並行性對於TCP的丟失恢復機制無論用,所以丟失或者從新排序的數據報都會致使全部活動事務陷入停頓。

爲了解決以上問題,因而Google發明了gQUIC(Quick UDP Internet Connection)協議。

1.6.一、QUIC

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

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

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

1.6.二、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 ↩︎

相關文章
相關標籤/搜索