http
HTTP(超文本傳輸協議,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標准。設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。是用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議。默認使用80端口,HTTP客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP連接。
HTTP協議和TCP協議是不沖突的,HTTP定義在七層協議中的應用層,TCP解決的是傳輸層的邏輯。HTTP使用TCP而不是UDP的原因在於(打開)一個網頁必須傳送很多數據,而TCP協議提供傳輸控制,按順序組織數據,和錯誤糾正。HTTP協議的瓶頸及其優化技巧都是基於TCP協議本身的特性。如TCP建立連接時三次握手有1.5個RTT(round-trip time)的延遲,為了避免每次請求的都經歷握手帶來的延遲,應用層會選擇不同策略的http長鏈接方案。又如TCP在建立連接的初期有慢啟動(slow start)的特性,所以連接的重用總是比新建連接性能要好。
HTTP連接使用的是“請求—響應”的方式,不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求后,服務器端才能回復數據。
HTTP/1.0是第一個在通訊中指定版本號的HTTP 協議版本,至今仍被廣泛采用,特別是在代理服務器中。HTTP/1.1是當前版本,持久連接被默認采用,並能很好地配合代理服務器工作,還支持以管道方式同時發送多個請求,以便降低線路負載,提高傳輸速度。HTTP/2.0在HTTP 1.x的基礎上,大幅度的提高了web性能,減少了網絡延遲。HTTP1.0和1.1在之后很長的一段時間內會一直並存,這是由於網絡基礎設施更新緩慢所決定的。
http 1.0
HTTP 協議老的標准是HTTP/1.0,為了提高系統的效率,HTTP 1.0規定瀏覽器與服務器只保持短暫的連接,瀏覽器的每次請求都需要與服務器建立一個TCP連接,服務器完成請求處理后立即斷開TCP連接,服務器不跟蹤每個客戶也不記錄過去的請求。
這造成了一些性能上的缺陷,例如,一個包含有許多圖像的網頁文件中並沒有包含真正的圖像數據內容,而只是指明了這些圖像的URL地址,當WEB瀏覽器訪問這個網頁文件時,瀏覽器首先要發出針對該網頁文件的請求,當瀏覽器解析WEB服務器返回的該網頁文檔中的HTML內容時,發現其中的圖像標簽后,瀏覽器將根據標簽中的src屬性所指定的URL地址再次向服務器發出下載圖像數據的請求。顯然,訪問一個包含有許多圖像的網頁文件的整個過程包含了多次請求和響應,每次請求和響應都需要建立一個單獨的連接,每次連接只是傳輸一個文檔和圖像,上一次和下一次請求完全分離。即使圖像文件都很小,但是客戶端和服務器端每次建立和關閉連接卻是一個相對比較費時的過程,並且會嚴重影響客戶機和服務器的性能。當一個網頁文件中包含JavaScript文件,CSS文件等內容時,也會出現類似上述的情況。
同時,帶寬和延遲也是影響一個網絡請求的重要因素。在網絡基礎建設已經使得帶寬得到極大的提升的當下,大部分時候都是延遲在於響應速度。基於此會發現,http1.0被抱怨最多的就是連接無法復用,和head of line blocking這兩個問題。
理解這兩個問題有一個十分重要的前提:
客戶端是依據域名來向服務器建立連接,一般PC端瀏覽器會針對單個域名的server同時建立6~8個連接,手機端的連接數則一般控制在4~6個。顯然連接數並不是越多越好,資源開銷和整體延遲都會隨之增大。連接無法復用會導致每次請求都經歷三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對文件類大請求影響較大。head of line blocking會導致帶寬無法被充分利用,以及后續健康請求被阻塞。
head of line blocking(holb)會導致健康的請求會被不健康的請求影響,而且這種體驗的損耗受網絡環境影響,出現隨機且難以監控。為了解決holb帶來的延遲,協議設計者設計了一種新的pipelining機制。pipelining只能適用於http1.1,而且由於使用苛刻,很多瀏覽器廠商並不支持。
HTTP1.1
為了克服HTTP 1.0的這個缺陷,HTTP1.1支持長連接(HTTP/1.1的默認模式使用帶流水線的長連接),在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲。
一個包含有許多圖像的網頁文件的多個請求和應答可以在一個連接中傳輸,但每個單獨的網頁文件的請求和應答仍然需要使用各自的連接。HTTP1.1還允許客戶端不用等待上一次請求結果返回,就可以發出下一次請求,但服務器端必須按照接收到客戶端請求的先后順序依次回送響應結果,以保證客戶端能夠區分出每次請求的響應內容,這樣也顯著地減少了整個下載過程所需要的時間。
在http1.1,request和reponse頭中都有可能出現一個connection的頭,此header的含義是當client和server通信時對於長鏈接如何進行處理。
在http1.1中,client和server都是默認對方支持長鏈接的, 如果client使用http1.1協議,但又不希望使用長鏈接,則需要在header中指明connection的值為close;如果server方也不想支持長鏈接,則在response中也需要明確說明connection的值為close。不論request還是response的header中包含了值為close的connection,都表明當前正在使用的tcp鏈接在當天請求處理完畢后會被斷掉。以后client再進行新的請求時就必須創建新的tcp鏈接了。
另外,HTTP 1.1通過增加更多的請求頭和響應頭來改進和擴充HTTP 1.0的功能。
- HTTP 1.0不支持Host請求頭字段,WEB瀏覽器無法使用主機頭名來明確表示要訪問服務器上的哪個WEB站點,這樣就無法使用WEB服務器在同一個IP地址和端口號上配置多個虛擬WEB站點。在HTTP 1.1中增加Host請求頭字段后,WEB瀏覽器可以使用主機頭名來明確表示要訪問服務器上的哪個WEB站點,這才實現了在一台WEB服務器上可以在同一個IP地址和端口號上使用不同的主機名來創建多個虛擬WEB站點。
- HTTP 1.1的持續連接,也需要增加新的請求頭來幫助實現,例如,Connection請求頭的值為Keep-Alive時,客戶端通知服務器返回本次請求結果后保持連接;Connection請求頭的值為close時,客戶端通知服務器返回本次請求結果后關閉連接。
- HTTP 1.1還提供了與身份認證、狀態管理和Cache緩存等機制相關的請求頭和響應頭。
- HTTP/1.0不支持文件斷點續傳,
RANGE:bytes
是HTTP/1.1新增內容,HTTP/1.0每次傳送文件都是從文件頭開始,即0字節處開始。RANGE:bytes=XXXX
表示要求服務器從文件XXXX字節處開始傳送,這就是我們平時所說的斷點續傳!
HTTP1.0和HTTP1.1的一些區別
-
緩存處理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires來做為緩存判斷的標准,HTTP1.1則引入了更多的緩存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的緩存頭來控制緩存策略。
-
帶寬優化及網絡連接的使用,HTTP1.0中,存在一些浪費帶寬的現象,例如客戶端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,並且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它允許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和連接。
-
錯誤通知的管理,在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生沖突;410(Gone)表示服務器上的某個資源被永久性的刪除。
-
Host頭處理,在HTTP1.0中認為每台服務器都綁定一個唯一的IP地址,因此,請求消息中的URL並沒有傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一台物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。
-
長連接,HTTP 1.1支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲,在HTTP1.1中默認開啟Connection: keep-alive,一定程度上彌補了HTTP1.0每次請求都要創建連接的缺點。
SPDY:HTTP2.0前身
SPDY與HTTP的關系
SPDY並不是一個標准協議,但SPDY的開發組推動SPDY成為正式標准,而成為了互聯網草案。后來SPDY未能單獨成為正式標准,不過SPDY開發組的成員全程參與了HTTP/2的制定過程。HTTP/2的關鍵功能主要來自SPDY技術,換言之,SPDY的成果被采納而最終演變為HTTP/2。HTTP/2協議完成之后,2015年9月,Google 宣布移除對SPDY的支持,擁抱 HTTP/2,並將在Chrome 51中生效。
http 1.1 | http1.1+SPDY |
---|---|
HTTP | HTTP |
- | SPDY |
SSL(可選) | SSL |
TCP | TCP |
SPDY並不用於取代HTTP,它只是修改了HTTP的請求與應答在網絡上傳輸的方式;這意味着只需增加一個SPDY傳輸層,現有的所有服務端應用均不用做任何修改。 當使用SPDY的方式傳輸,HTTP請求會被處理、標記簡化和壓縮。
SPDY新特性
-
多路復用
降低延遲,針對HTTP高延遲的問題,SPDY優雅的采取了多路復用(multiplexing)。多路復用通過多個請求stream共享一個tcp連接的方式,解決了HOL blocking的問題,降低了延遲同時提高了帶寬的利用率。
-
請求優先級(request prioritization)。
多路復用帶來一個新的問題是,在連接共享的基礎之上有可能會導致關鍵請求被阻塞。SPDY允許給每個request設置優先級,這樣重要的請求就會優先得到響應。比如瀏覽器加載首頁,首頁的html內容應該優先展示,之后才是各種靜態資源文件,腳本文件等加載,這樣可以保證用戶能第一時間看到網頁內容。
-
header壓縮。
HTTP1.x的header很多時候都是重復多余的。選擇合適的壓縮算法可以減小包的大小和數量。
-
基於HTTPS的加密協議傳輸
大大提高了傳輸數據的可靠性。
-
服務端推送(server push)
采用了SPDY的網頁,例如我的網頁有一個sytle.css的請求,在客戶端收到sytle.css數據的同時,服務端會將sytle.js的文件推送給客戶端,當客戶端再次嘗試獲取sytle.js時就可以直接從緩存中獲取到,不用再發請求了。
http 2.0
https://http2.akamai.com/demo http2.0測試網址
HTTP2.0和SPDY的區別
-
HTTP2.0 支持明文 HTTP 傳輸,而 SPDY 強制使用 HTTPS
HTTP2.0可以支持非HTTPS,但是現在主流的瀏覽器像chrome,firefox表示還是只支持基於 TLS 部署的HTTP2.0協議,所以要想升級成HTTP2.0還是先升級HTTPS為好。
-
HTTP2.0 消息頭的壓縮算法采用 HPACK,而非 SPDY 采用的 DEFLATE
HTTP2.0和HTTP1.X相比的新特性
多路復用 (Multiplexing)
多路復用允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。在 HTTP/1.1 協議中瀏覽器客戶端在同一時間,針對同一域名下的請求有一定數量限制。超過限制數目的請求會被阻塞。這也是為何一些站點會有多個靜態資源 CDN 域名的原因之一,而 HTTP/2 的多路復用(Multiplexing) 則允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。因此 HTTP/2 可以很容易的去實現多流並行而不用依賴建立多個 TCP 連接,HTTP/2 把 HTTP 協議通信的基本單位縮小為一個一個的幀,這些幀對應着邏輯流中的消息。並行地在同一個 TCP 連接上雙向交換消息。
多路復用即連接共享,即每一個request都是是用作連接共享機制的。一個request對應一個id,這樣一個連接上可以有多個request,每個連接的request可以隨機的混雜在一起,接收方可以根據request的id將request再歸屬到各自不同的服務端請求里面。
HTTP2.0的多路復用和HTTP1.1中的長連接復用有什么區別?
-
HTTP/1.* 一次請求-響應,建立一個連接,用完關閉;每一個請求都要建立一個連接;
-
HTTP/1.1 Pipeling解決方式為,若干個請求排隊串行化單線程處理,后面的請求等待前面請求的返回才能獲得執行機會,一旦有某請求超時等,后續請求只能被阻塞,毫無辦法,也就是人們常說的線頭阻塞;
-
HTTP/2多個請求可同時在一個連接上並行執行。某個請求任務耗時嚴重,不會影響到其它連接的正常執行
HTTP2.0多路復用有多好?
HTTP 性能優化的關鍵並不在於高帶寬,而是低延遲。TCP 連接會隨着時間進行自我「調諧」,起初會限制連接的最大速度,如果數據成功傳輸,會隨着時間的推移提高傳輸的速度。這種調諧則被稱為 TCP 慢啟動。由於這種原因,讓原本就具有突發性和短時性的 HTTP 連接變的十分低效。HTTP/2 通過讓所有數據流共用同一個連接,可以更有效地使用 TCP 連接,讓高帶寬也能真正的服務於 HTTP 的性能提升。
請求優先級
多路復用帶來一個新的問題是,在連接共享的基礎之上有可能會導致關鍵請求被阻塞。
HTTP 2.0允許給每個request設置優先級。
HTTP 2.0 使用一個31比特的優先值,0表示最高優先級, 2(31)-1表示最低優先級,服務器端就可以根據優先級,控制資源分配,優先處理和返回最高優先級的請求幀給客戶端。
二進制分幀
HTTP1.1的解析是基於文本。基於文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合。基於這種考慮HTTP2.0的協議解析決定采用二進制格式,實現方便且健壯。
HTTP/2在 應用層(HTTP/2)和傳輸層(TCP or UDP)之間增加一個二進制分幀層。在不改動 HTTP/1.x 的語義、方法、狀態碼、URI 以及首部字段的情況下, 解決了HTTP1.1 的性能限制,改進傳輸性能,實現低延遲和高吞吐量。
在二進制分幀層中, HTTP/2 會將所有傳輸的信息分割為更小的消息和幀(frame),並對它們采用二進制格式的編碼 ,其中 HTTP1.x 的首部信息會被封裝到 HEADER frame,而相應的 Request Body 則封裝到 DATA frame 里面。
HTTP/2 通信都在一個連接上完成,這個連接可以承載任意數量的雙向數據流。
在過去, HTTP 性能優化的關鍵並不在於高帶寬,而是低延遲。TCP 連接會隨着時間進行自我調諧,起初會限制連接的最大速度,如果數據成功傳輸,會隨着時間的推移提高傳輸的速度。這種調諧則被稱為 TCP 慢啟動。由於這種原因,讓原本就具有突發性和短時性的 HTTP 連接變的十分低效。HTTP/2 通過讓所有數據流共用同一個連接,可以更有效地使用 TCP 連接,讓高帶寬也能真正的服務於 HTTP 的性能提升。
這種單連接多資源的方式,減少服務端的鏈接壓力,內存占用更少,連接吞吐量更大;而且由於 TCP 連接的減少而使網絡擁塞狀況得以改善,同時慢啟動時間的減少,使擁塞和丟包恢復速度更快。
頭部壓縮(Header Compression)
HTTP/1.1並不支持 HTTP 首部壓縮,為此 SPDY 和 HTTP/2 應運而生, SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 則使用了專門為首部壓縮而設計的 HPACK 算法。
為什么需要頭部壓縮?
假定一個頁面有100個資源需要加載(這個數量對於今天的Web而言還是挺保守的), 而每一次請求都有1kb的消息頭(這同樣也並不少見,因為Cookie和引用等東西的存在), 則至少需要多消耗100kb來獲取這些消息頭。HTTP2.0可以維護一個字典,差量更新HTTP頭部,大大降低因頭部傳輸產生的流量。
通訊雙方各自cache一份header fields表,既避免了重復header的傳輸,又減小了需要傳輸的大小。
服務端推送(Server Push)
在 HTTP/2 中,服務器可以對客戶端的一個請求發送多個響應。
Server Push 讓 HTTP1.x時代使用內嵌資源的優化手段變得沒有意義;如果一個請求是由你的主頁發起的,服務器很可能會響應主頁內容、logo 以及樣式表,因為它知道客戶端會用到這些東西。這相當於在一個 HTML 文檔內集合了所有的資源,不過與之相比,服務器推送還有一個很大的優勢:可以緩存!也讓在遵循同源的情況下,不同頁面之間可以共享緩存資源成為可能。
參考
HTTP 1.0狀態碼
- 200 OK 一切正常,對GET和POST請求的應答文檔跟在后面。
- 201 Created 服務器已經創建了文檔,Location頭給出了它的URL。
- 202 Accepted 已經接受請求,但處理尚未完成。
-
300 Multiple Choices客戶請求的文檔可以在多個位置找到,這些位置已經在返回的文檔內列出。如果服務器要提出優先選擇,則應該在Location應答頭指明。
-
301 Moved Permanently 客戶請求的文檔在其他地方,新的URL在Location頭中給出,瀏覽器應該自動地訪問新的URL。
-
302 Found 類似於301,但新的URL應該被視為臨時性的替代,而不是永久性的。注意,在HTTP1.0中對應的狀態信息是“Moved Temporatily”。
出現該狀態代碼時,瀏覽器能夠自動訪問新的URL,因此它是一個很有用的狀態代碼。
注意這個狀態代碼有時候可以和301替換使用。例如,如果瀏覽器錯誤地請求http://host/~user(缺少了后面的斜杠),有的服務器返回301,有的則返回302。
嚴格地說,我們只能假定只有當原來的請求是GET時瀏覽器才會自動重定向。請參見307。 -
304 Not Modified 客戶端有緩沖的文檔並發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩沖的文檔還可以繼續使用。
- 400 Bad Request 請求出現語法錯誤。
- 401 Unauthorized 客戶試圖未經授權訪問受密碼保護的頁面。應答中會包含一個WWW-Authenticate頭,瀏覽器據此顯示用戶名字/密碼對話框,然后在填寫合適的Authorization頭后再次發出請求。
- 403 Forbidden 資源不可用。服務器理解客戶的請求,但拒絕處理它。通常由於服務器上文件或目錄的權限設置導致。
- 404 Not Found 無法找到指定位置的資源。這也是一個常用的應答。
- 500 Internal Server Error 服務器遇到了意料不到的情況,不能完成客戶的請求。
- 501 Not Implemented 服務器不支持實現請求所需要的功能。例如,客戶發出了一個服務器不支持的PUT請求。
- 502 Bad Gateway 服務器作為網關或者代理時,為了完成請求訪問下一個服務器,但該服務器返回了非法的應答。
- 503 Service Unavailable 服務器由於維護或者負載過重未能應答。例如,Servlet可能在數據庫連接池已滿的情況下返回503。服務器返回503時可以提供一個Retry-After頭。
HTTP 1.1新增狀態碼
- 100 Continue 初始的請求已經接受,客戶應當繼續發送請求的其余部分。(HTTP 1.1新)
- 101 Switching Protocols 服務器將遵從客戶的請求轉換到另外一種協議(HTTP 1.1新)
- 203 Non-Authoritative Information 文檔已經正常地返回,但一些應答頭可能不正確,因為使用的是文檔的拷貝(HTTP 1.1新)。
- 204 No Content 沒有新文檔,瀏覽器應該繼續顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個狀態代碼是很有用的。
- 205 Reset Content 沒有新的內容,但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容(HTTP 1.1新)。
- 206 Partial Content 客戶發送了一個帶有Range頭的GET請求,服務器完成了它(HTTP 1.1新)。
- 303 See Other 類似於301/302,不同之處在於,如果原來的請求是POST,Location頭指定的重定向目標文檔應該通過GET提取(HTTP 1.1新)。
- 305 Use Proxy 客戶請求的文檔應該通過Location頭所指明的代理服務器提取(HTTP 1.1新)。
- 307 Temporary Redirect 和302(Found)相同。許多瀏覽器會錯誤地響應302應答進行重定向,即使原來的請求是POST,即使它實際上只能在POST請求的應答是303時 才能重定向。由於這個原因,HTTP 1.1新增了307,以便更加清除地區分幾個狀態代碼:當出現303應答時,瀏覽器可以跟隨重定向的GET和POST請求;如果是307應答,則瀏覽器只能跟隨對GET請求的重定向。(HTTP 1.1新)
- 405 Method Not Allowed 請求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)對指定的資源不適用。(HTTP 1.1新)
- 406 Not Acceptable 指定的資源已經找到,但它的MIME類型和客戶在Accpet頭中所指定的不兼容(HTTP 1.1新)。
- 407 Proxy Authentication Required 類似於401,表示客戶必須先經過代理服務器的授權。(HTTP 1.1新)
- 408 Request Timeout 在服務器許可的等待時間內,客戶一直沒有發出任何請求。客戶可以在以后重復同一請求。(HTTP 1.1新)
- 409 Conflict 通常和PUT請求有關。由於請求和資源的當前狀態相沖突,因此請求不能成功。(HTTP 1.1新)
- 410 Gone 所請求的文檔已經不再可用,而且服務器不知道應該重定向到哪一個地址。它和404的不同在於,返回407表示文檔永久地離開了指定的位置,而404表示由於未知的原因文檔不可用。(HTTP 1.1新)
- 411 Length Required 服務器不能處理請求,除非客戶發送一個Content-Length頭。(HTTP 1.1新)
- 412 Precondition Failed 請求頭中指定的一些前提條件失敗(HTTP 1.1新)。
- 413 Request Entity Too Large 目標文檔的大小超過服務器當前願意處理的大小。如果服務器認為自己能夠稍后再處理該請求,則應該提供一個Retry-After頭(HTTP 1.1新)。
- 414 Request URI Too Long URI太長(HTTP 1.1新)。
- 416 Requested Range Not Satisfiable 服務器不能滿足客戶在請求中指定的Range頭。(HTTP 1.1新)
- 504 Gateway Timeout 由作為代理或網關的服務器使用,表示不能及時地從遠程服務器獲得應答。(HTTP 1.1新)
- 505 HTTP Version Not Supported 服務器不支持請求中所指明的HTTP版本。(HTTP 1.1新)