超文本傳輸協議(HTTP)是互聯網上最廣泛並普遍採用的應用協議之一:它是客戶端和服務器之間的通用語言,促成了現代網絡的造成。最開始它以單關鍵字和文檔路徑的簡單形式出現,目前已成爲不只僅是瀏覽器,幾乎每一個互聯網鏈接的軟件和硬件應用程序所選擇的協議。html
在本章中,咱們將簡要介紹HTTP協議的演進。對不一樣HTTP語義的完整討論超出了本書的範圍,可是瞭解HTTP的關鍵設計變動及其背後的動機將爲咱們討論HTTP性能提供必要的知識儲備,特別是在許多即將到來的HTTP/2改進的背景下。nginx
Tim Berners-Lee提出最初的HTTP提案設計時,考慮到了其簡單性,這幫助了他採用他的新想法:萬維網。彷佛策略被應用以後,這位有抱負的協議設計者才進入你們的視野。程序員
1991年,Berners-Lee概述了新協議的動機,列出了幾個高級設計目標:文件傳輸,對超文本進行索引搜索並將其存檔,格式協商以及由客戶端向服務器發出請求。爲了切實地證實理論,Berners-Lee創建了一個簡單的原型,實現了所提出的功能的一小部分:web
客戶端請求是單個ASCII字符串。瀏覽器
客戶端請求由回車(CRLF)終止。緩存
服務器響應是一個ASCII字符流。性能優化
服務器響應是一種超文本標記語言(HTML)。服務器
文檔傳輸完成後,鏈接終止。cookie
然而,即便這聽起來比它實際更復雜。這些規則支持的是一個很是簡單的,對Telnet友好的協議,一些Web服務器很快就能支持它:網絡
$> telnet google.com 80 Connected to 74.125.xxx.xxx GET /about/ (hypertext response) (connection closed)
請求由單行:GET方法和所請求文檔的路徑組成。響應是單個超文本文檔 - 沒有頭或任何其餘元數據,只是HTML。它真的再簡單不過了。此外,因爲先前的交互是預協議的子集,因此它非正式地獲取HTTP 0.9標籤。衆所周知,一些協議子集已成爲歷史。
1991年HTTP初具雛形,HTTP接受了本身的生活,並在將來幾年迅速發展。讓咱們快速回顧一下HTTP 0.9的特性:
客戶端 - 服務器,請求 - 響應協議。
經過TCP / IP鏈路運行的ASCII協議。
被設計用於傳輸超文本文件(HTML)。
每次請求後,服務器和客戶端之間的鏈接關閉。
流行的Web服務器,如Apache和Nginx,仍然支持部分的HTTP0.9協議(HTTP0.9內容並很少)。若是你好奇,打開Telnet會話,並嘗試經過HTTP 0.9訪問google.com或您本身喜歡的網站,並查看此早期協議的行爲和侷限性。
HTTP / 1.0:快速生長和信息RFC
1991年到1995年是HTML規範(一種被稱爲「網絡瀏覽器」的新型軟件)和 以消費者爲導向的公共互聯網基礎設施的快速協同增加時期。
完美風暴:在20世紀90年代早期的互聯網熱潮
基於Tim Berner-Lee的瀏覽器原型,國家超級計算應用中心(NCSA)的一個團隊決定實施本身的版本。這樣,第一個流行的瀏覽器NCSA Mosaic誕生了。NCSA團隊的一名程序員Marc Andreessen與Jim Clark合做,於1994年10月成立了Mosaic通信公司,後來改名爲Netscape,並於1994年12月發佈了Netscape Navigator 1.0。至此,萬維網在你們心中的意義已經不只限於學術上的探索。
事實上,同年在瑞士日內瓦舉辦了第一次萬維網會議,會議上萬維網聯盟(W3C)建立,以幫助指導HTML的發展。與此同時,在IETF內部創建並行的HTTP工做組(HTTP-WG)也致力於HTTP協議的改進。這兩個組織持續推進了網絡的發展。
最後,這場完美的風暴中,還有一個重大舉措:CompuServe,AOL和Prodigy在1994 - 1995年的同一時間段內開始向公衆提供撥號上網。在技術快速變現的浪潮中,Netscape在1995年8月9日成功舉辦了一次很是成功的IPO,互聯網熱潮已經到來,每一個人都想參與其中!
HTTP 0.9並不能很好地知足新興網絡的需求,而且實際的使用也暴露了HTTP 0.9的許多基本限制:咱們須要一個協議,不只能夠服務於超文本文檔,還能夠提供更多關於請求的元數據響應,啓用內容協商等。而在實際應用中,網絡開發人員的新生社區經過你們共同推進的過程,生成了大量實驗性HTTP服務器和客戶端,經過這些實驗性的實施部署查看用戶的使用傾向。
從這個社區積極推進的實驗時期開始,出現了一套最佳作法和常見模式,1996年5月,HTTP工做組(HTTP-WG)發佈了RFC 1945,該文件記錄了許多最後在HTTP / 1.0中被採用的野生用法。請注意,這只是一些信息彙總RFC:HTTP / 1.0,咱們知道它不是正式規範或Internet標準!
話雖如此,HTTP / 1.0的示例應該看起來很熟悉:
$> telnet website.org 80 Connected to xxx.xxx.xxx.xxx GET /rfc/rfc1945.txt HTTP/1.0 //請求行與HTTP版本號,後跟請求頭 User-Agent: CERN-LineMode/2.15 libwww/2.17b3 Accept: */ * HTTP/1.0 200 OK //響應狀態,後跟響應頭 Content-Type: text/plain Content-Length: 137582 Expires: Thu, 01 Dec 1997 16:00:00 GMT Last-Modified: Wed, 1 May 1996 12:45:26 GMT Server: Apache 0.84 (plain-text response) (connection closed)
上述消息機制不是HTTP / 1.0功能的詳盡列表,但它說明了一些關鍵協議更改:
請求可能包含多個換行標題字段。
響應對象以響應狀態行爲前綴。
響應對象有本身的一行以換行符分隔的頭部。
響應對象不限於超文本。
每一個請求後,服務器和客戶端之間的鏈接關閉。
請求頭和響應頭都保存爲ASCII編碼,但響應對象自己能夠是任何類型:HTML文件,純文本文件,圖像或任何其餘內容類型。所以,HTTP的「超文本傳輸」部分在引入後不久很容易被人們誤會。在現實中,HTTP已迅速發展成爲一個超媒體傳輸,但原來的名字依舊被保留。
除媒體類型協商外,RFC還記錄了許多其餘經常使用功能:內容編碼,字符集支持,多類型,受權,緩存,代理行爲,日期格式等。
今天,網絡上幾乎每一個服務器還是以HTTP / 1.0的協議傳輸的。除此以外,你應該很清楚!每一個請求都要有新的TCP鏈接,對HTTP / 1.0是很大的性能損失; 參見三次握手,還有慢啓動。
從1995年至1999年,HTTP / 1.0的文檔化在逐步推動,歷時4年,HTTP成爲官方IETF互聯網的標準。事實上,大約在HTTP / 1.0發佈後六個月,第一個官方HTTP / 1.1標準定義在RFC 2068中,於1997年1月就正式發佈。兩年半後,1999年6月,一些改進和更新被歸入標準,並做爲RFC 2616發佈。
HTTP / 1.1標準規範了許多早期版本中的不清晰的協議內容,並引入了不少關鍵性能優化:持續鏈接,分塊編碼傳輸,以字節爲單位的請求,另外還有緩存機制,傳輸編碼和請求管線化(多個HTTP請求整批提交的技術)。
有了這些功能,咱們如今能夠經過在任何現代瀏覽器和客戶端運用HTTP,觀察典型的HTTP / 1.1會話:
$> telnet website.org 80 Connected to xxx.xxx.xxx.xxx GET /index.html HTTP/1.1 //請求HTML文件,其中包含編碼,字符集和Cookie元數據 Host: website.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: __qca=P0-800083390... (snip) HTTP/1.1 200 OK //針對原始HTML請求的分塊響應 Server: nginx/1.0.11 Connection: keep-alive Content-Type: text/html; charset=utf-8 Via: HTTP/1.1 GWA Date: Wed, 25 Jul 2012 20:23:35 GMT Expires: Wed, 25 Jul 2012 20:23:35 GMT Cache-Control: max-age=0, no-cache Transfer-Encoding: chunked 100 //塊中的八位字節數以ASCII十六進制數表示(256字節) <!doctype html> (snip) 100 (snip) 0 //分塊流響應結束 GET /favicon.ico HTTP/1.1 //請求在同一個TCP鏈接上圖標文件 Host: www.website.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip) Accept: */ * Referer: http://website.org/ Connection: close //通知服務器鏈接不會被重用 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: __qca=P0-800083390... (snip) HTTP/1.1 200 OK //圖標響應,以後鏈接關閉 Server: nginx/1.0.11 Content-Type: image/x-icon Content-Length: 3638 Connection: close Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT Cache-Control: max-age=315360000 Accept-Ranges: bytes Via: HTTP/1.1 GWA Date: Sat, 21 Jul 2012 21:35:22 GMT Expires: Thu, 31 Dec 2037 23:55:55 GMT Etag: W/PSA-GAu26oXbDi (icon data) (connection closed)
呃,這期間其實發生了不少事情!第一個也是最明顯的區別是,咱們有兩個對象請求,一個用於HTML頁面,另外一個用於圖像,二者都經過單個鏈接傳遞。每次鏈接都是持續的,這容許咱們重複使用現有的TCP鏈接實現多個請求到相同的主機,並提供更快的終端用戶體驗; 參閱優化TCP。
要終止持久鏈接,你將會注意到,第二客戶端在請求的鏈接頭中發送了顯式關閉令牌到服務器。相似地,服務器能夠在傳輸響應時,通知客戶端它意圖關閉當前TCP鏈接。從技術上講,任何一方均可以在任什麼時候候終止TCP鏈接而無需這種信號,但客戶端和服務器應儘量提供它,以便使雙方實現更好的鏈接重用策略。
默認狀況下,HTTP / 1.1使用持續連接,這是在HTTP協議語義上作出的更改。這意味着,除非另行告知(經過 Connection: close頭),服務器應該保持鏈接默認打開。
然而,這種相同的功能經過啓用Connection: Keep-Alive報頭,也被反向移植到HTTP / 1.0。所以,若是你正在使用HTTP / 1.1,在技術上你不須要的 Connection: Keep-Alive頭,但許多客戶選擇仍然提供。
此外,HTTP / 1.1協議添加了內容,編碼,字符集,甚至語言協商,傳輸編碼,緩存指令,客戶端cookie,以及能夠在每一個請求上協商的十幾個其餘功能。
咱們不會講述每一個HTTP / 1.1功能的語義。這是一本專門的HTTP協議書該作的,許多偉大的書已經作得很好。並且,前面的例子很好地說明了HTTP的快速進展和進化,以及每一個客戶端 - 服務器錯綜複雜的優雅信息交換機制。那裏有不少地方值得探索!
推薦一個有關HTTP協議全部工做機制的參考:O’Reilly’s HTTP: David Gourley 和 Brian Totty 寫的權威指南.
自從問世以來,RFC 2616已經成爲互聯網史無前例的發展基礎:數十億種各類形狀和大小的設備,從臺式電腦到咱們口袋裏的小型網絡設備,天天都會傳出HTTP,它提供新聞,視頻,以及數百萬其餘咱們生活中依賴的網絡應用程序。
最開始的一個簡單的單行協議檢索超文本快速演變成一個通用的超媒體傳輸,十年之後的如今,它能夠用來知足任何你能夠想象的使用場景。能夠說服務器使用協議之廣泛,用戶在客戶端的使用之普遍,意味着許多應用程序如今是專門設計和部署在HTTP之上的。
須要一個協議來控制你的咖啡壺?RFC 2324已經覆蓋了超文本咖啡壺控制協議(HTCPCP / 1.0) - 這是最初是IETF的愚人節玩笑,超連接爲咱們打開了新世界的大門。
超文本傳輸協議(HTTP)是用於分佈式,協做的超媒體信息系統的應用級協議。它是一種通用的,無狀態的協議,能夠經過擴展其請求方法,錯誤代碼和頭部信息,將其用於許多超出超文本使用的任務,如域名解析和分佈式對象管理系統。HTTP的一個特徵是數據表示的歸類和協商,容許系統獨立於要傳輸的數據。RFC 2616:HTTP / 1.1,1999年6月
HTTP協議的簡單性使其最初能夠被採用而且可以快速發展。事實上,如今在嵌入式設備 - 傳感器,執行器和咖啡壺中,使用HTTP做爲主要協議進行數據控制是很廣泛的。可是,在如此的重大成功之下,隨着咱們愈來愈多的社交,電子郵件,新聞和視頻等平常互動的網絡化,以及愈來愈多的我的和工做空間,HTTP協議面臨着壓力。用戶和Web開發人員須要應用的實時響應,也就是高性能協議,僅在HTTP / 1.1基礎上進行修改是不能知足需求的。
爲了應對這些新的挑戰,HTTP必須繼續發展,所以,HTTPbis工做組在2012年初發布了一個新的HTTP / 2計劃:
在協議中有新的實現經驗和關注點,該協議保留了HTTP的語義,而沒有HTTP / 1.x消息框架和語法的遺留,由於它們影響性能並鼓勵濫用底層傳輸。
工做組將以有序的雙向流的形式給出HTTP當前語義的新表達式規範。與HTTP / 1.x同樣,主要採用TCP,也可使用其餘傳輸。
HTTP / 2章程,2012年1月
HTTP / 2的主要重點是改善傳輸性能,同時實現更低的延遲和更高的吞吐量。主要版本的更新聽起來跨度很大,它在性能方面的確有不少改善,但值得注意的是,沒有一個高級協議語義受到影響:全部HTTP頭,值和用例是相同的。
任何現有的網站或應用程序均可以經過HTTP / 2進行交付,無需修改:您不須要修改應用程序標記,以利用HTTP / 2。HTTP服務器將不得不升級爲HTTP / 2,但這應該是對大多數用戶的透明升級。惟一的區別,若是工做組達到其目標,咱們的應用程序交付將要具備更低的延遲和更好網絡連接利用!
話雖如此,別高興得太早。在咱們得到新的HTTP / 2協議功能以前,應該退一步,總結咱們現有的HTTP / 1.1的部署和性能最佳實踐。HTTP / 2工做組正在快速推出新規範,但即便最終標準已經完成並準備就緒,咱們仍然能夠在可預見的未來支持較舊的HTTP / 1.1客戶端。