HTTP概述
HTTP協(xié)議用于約定服務端(如Web服務器Tomcat难捌、IIS)和客戶端(如瀏覽器、APP)通信的消息格式和響應方式鸦难。了解HTTP協(xié)議內容有助于優(yōu)化Http請求根吁,如斷點下載、多線程下載合蔽、防盜鏈等功能的實現(xiàn)击敌。HTTP協(xié)議是建立在TCP協(xié)議之上的,理論上只要有一個Socket就能夠實現(xiàn)Http消息的請求拴事,實現(xiàn)比如HttpClient沃斤、UrlConnection的請求操作。只要有一個SocketServer就能夠實現(xiàn)Http消息的響應刃宵,實現(xiàn)比如Tomcat衡瓶、IIS等Web服務器的功能,比如在手機上部署網(wǎng)站牲证,用戶可以在瀏覽器端訪問同一網(wǎng)絡下的手機部署的站點哮针。
HTTP請求協(xié)議詳解
HTTP1.1的請求協(xié)議報文結構如下圖,大體上可以分為三塊,即請求行十厢、頭部等太、消息主體。
請求行
請求行包含HTTP請求方法寿烟、請求的URL澈驼、HTTP協(xié)議版本三個內容,它們之間以空格間隔筛武,并以回車+換行結束缝其。
HTTP請求方法有下面幾種,常用的有GET、POST請求徘六。
- OPTIONS
- GET
- HEAD
- POST
- DELETE
- TRACE
- CONNECT
請求頭部
頭部可以分成三個部分内边,為常用頭域、請求頭域待锈、實體頭域漠其。其中常用頭域和實體頭域部分內容在響應協(xié)議部分也有相同的定義。
常用頭域
常用頭域名稱 | 作用描述 |
---|---|
Cache-Control | 緩存控制 |
Connection | HTTP 1.1默認是支持長連接的(Keep-Alive)竿音,如果不希望支持長連接則需要在此域中寫入close |
Date | 表明消息產(chǎn)生的日期和時間 |
Pragma | |
Trailer | |
Transfer-Encoding | 告知接收端為了保證報文的可靠傳輸和屎,對報文采用了什么編碼方式 |
Upgrade | 給出了發(fā)送端可能想要”升級”使用的新版本或協(xié)議 |
Via | 顯示了報文經(jīng)過的中間節(jié)點(代理、網(wǎng)關) |
Warning |
請求頭域
請求頭域名稱 | 作用描述 |
---|---|
Accept | 指明請求端可以接受處理的媒體類型 |
Accept-Charset | 指明請求端可以接受的字符集 |
Accept-Encoding | 指明請求端可以接受的編碼格式 |
Authorization | 授權 |
Expect | 允許客戶端列出某請求所要求的服務器行為 |
From | 提供了客戶端用戶的E-mail地址 |
Host | 指明請求端的網(wǎng)絡主機和端口號 |
If-Match | 服務端在響應頭部里面返回ETag信息春瞬,客戶端請求時在頭部添加If-Match(值為響應的ETag)柴信,服務端接收后判斷ETag是否相同,若相同則處理請求宽气,否則不處理請求随常。 |
If-Modified-Since | 客戶端在請求某一資源文件時,在頭部加上If-Modified-Since(值為該資源文件的最后修改時間)萄涯,服務端接收后將客戶端上報的修改時間與服務器存儲的文件的最后修改時間做對比绪氛,如果相同,說明資源文件沒有更新涝影,返回304狀態(tài)碼枣察,告訴客戶端使用原來的緩存文件。否則返回資源內容燃逻。 |
If-None-Match | 服務端在響應頭部里面返回ETag信息序目,客戶端請求時在頭部添加If-None-Match(值為響應的ETag),服務端接收后判斷ETag是否相同唆樊,若相同宛琅,說明資源沒有更新刻蟹,返回304狀態(tài)碼逗旁,告訴客戶端使用原來的緩存文件。否則返回資源內容。 |
If-Range | 該頭域與Range頭域一起使用片效,服務端在響應頭部里面返回ETag信息,客戶端請求時在頭部添加If-Range(值為響應的ETag)红伦,服務端接收后判斷ETag是否相同,若相同淀衣,則返回狀態(tài)碼206昙读,返回內容為Range指定的字節(jié)范圍。若不相同膨桥,則返回狀態(tài)碼200蛮浑,返回內容為整個實體。 |
If-Unmodified-Since | 客戶端在請求某一資源文件時只嚣,在頭部加上If-Modified-Since(值為該資源文件的最后修改時間)沮稚,端接收后將客戶端上報的修改時間與服務器存儲的文件的最后修改時間做對比,如果相同册舞,則返回資源內容蕴掏,如果不相同則返回狀態(tài)碼412。 |
Max-Forwards | 配合TRACE调鲸、OPTIONS方法使用盛杰,限制在通往服務器的路徑上的代理或網(wǎng)關的數(shù)量。 |
Proxy-Authorization | 代理授權 |
Range | 表示客戶端向服務端請求指定范圍的字節(jié)數(shù)量:Range:bytes=0-500表示請求第1個到第501個的字節(jié)數(shù)量藐石。Range:bytes=100-表示請求第101到文件倒數(shù)第一個字節(jié)的字節(jié)數(shù)量即供。Range:bytes=-500表示請求最后500個字節(jié)的數(shù)量。Range可以同時指定多組(Range:bytes=500-600,601-999)贯钩。并不是所有的服務端都支持字節(jié)范圍請求的募狂,如果支持字節(jié)范圍請求,服務端會返回狀態(tài)碼206角雷,若不支持則會返回200祸穷,客戶端需要根據(jù)狀態(tài)碼來判斷服務端是否支持字節(jié)范圍操作。此域可用于斷點下載勺三,即在斷點處請求后面的內容雷滚,也可用于多線程下載同一個文件,每個線程負責一個文件的一部分下載工作吗坚,多個線程協(xié)同完成整個文件的下載祈远。 |
Referer | 用于指定客戶端請求的來源,是從搜索引擎過來的商源?還是從其它網(wǎng)站鏈接過來的车份?服務器根據(jù)此域,有時可以用做防盜鏈處理牡彻,不在指定范圍內的來源扫沼,統(tǒng)統(tǒng)拒絕出爹。 |
TE | 指明客戶端可以接受哪些傳輸編碼。 |
實體頭域
實體頭域名稱 | 作用描述 |
---|---|
Allow | 指明被請求的資源所支持的方法缎除,如GET严就、HEAD、PUT |
Content-Encoding | 指明實體內容所采用的編碼方式 |
Content-Language | 指明實體內容使用的語言 |
Content-Length | 指明請求實體的字節(jié)數(shù)量 |
Content-Location | 可以用來為實體提供對應資源的位置 |
Content-MD5 | 指定實體內容的MD5器罐,用于內容的完整性校驗(base64的128位MD5) |
Content-Range | |
Content-Type | 指定實體的媒體類型 |
Expires | 指明實體的過期時間 |
Last-Modified | 指明實體最后被修改的時間 |
HTTP響應協(xié)議詳解
HTTP1.1的響應協(xié)議報文結構如下圖梢为,大體上可以分為三塊,即狀態(tài)行轰坊、頭部铸董、消息主體。
狀態(tài)行
狀態(tài)行包含HTTP協(xié)議版本肴沫、狀態(tài)碼袒炉、原因短語三個內容,它們之間以空格間隔樊零,并以回車+換行結束我磁。
狀態(tài)碼由三位數(shù)字組成,第一位數(shù)字定義了響應類型驻襟,主要有如下五種類型的狀態(tài)碼
狀態(tài)碼類型 | 作用描述 |
---|---|
1xx | 報告(請求被接收夺艰,繼續(xù)處理) |
2xx | 成功(請求被成功的接收并處理) |
3xx | 重發(fā) |
4xx | 客戶端出錯(客戶端錯誤的協(xié)議格式和不能處理的請求) |
5xx | 服務器出錯(服務器無法完成有效的請求處理) |
狀態(tài)碼和對應的原因短語詳細描述
狀態(tài)碼 | 原因短語 | 中文描述 |
---|---|---|
100 | Continue | 繼續(xù) |
101 | Switching Protocols | 切換協(xié)議 |
200 | OK | 成功 |
201 | Created | 已創(chuàng)建 |
202 | Accepted | 接受 |
203 | Non-Authoritative information | 非權威信息 |
204 | No Content | 無內容 |
205 | Reset Content | 重置內容 |
206 | Partial Content | 部分內容 |
300 | Multiple Choices | 多個選擇 |
301 | Moved Permanently | 永久移動 |
302 | Found | 發(fā)現(xiàn) |
303 | See Other | 見其它 |
304 | Not Modified | 沒有改變 |
305 | Use Proxy | 使用代理 |
307 | Temporary Redirect | 臨時重發(fā) |
400 | Bad Request | 壞請求 |
401 | Unauthorized | 未授權的 |
402 | Payment Required | 必需的支付 |
403 | Forbidden | 禁用 |
404 | Not Found | 沒有找到 |
405 | Method Not Allowed | 方法不被允許 |
406 | Not Acceptable | 不可接受的 |
407 | Proxy Authentication Required | 需要代理驗證 |
408 | Request Timeout | 請求超時 |
409 | Confilict | 沖突 |
410 | Gone | 不存在 |
411 | Length Required | 長度必需 |
412 | Precondition Failed | 先決條件失敗 |
413 | Request Entity Too Large | 請求實體太大 |
414 | Request-URI Too Long | 請求URI太長 |
415 | Unsupported Media Type | 不支持的媒體類型 |
416 | Requested Range Not Satisfiable | 請求范圍不被滿足 |
417 | Expectation Failed | 期望失敗 |
500 | Internal Server Error | 內部服務器錯誤 |
501 | Not Implemented | 服務端沒有實現(xiàn) |
502 | Bad Gateway | 壞網(wǎng)關 |
503 | Service Unavailable | 服務不能獲得 |
504 | Gateway Timeout | 網(wǎng)關超時 |
505 | HTTP Version Not Supported | HTTP協(xié)議版本不支持 |
響應頭域
響應頭域名稱 | 作用描述 |
---|---|
Accept-Ranges | 服務器向客戶端指明服務器對范圍請求的接受度 |
Age | 從原始服務器到代理緩存形成的估算時間(以秒計,非負) |
ETag | 實體標簽 |
Location | 指定重定向的URI |
Proxy-Autenticate | 它指出認證方案和可應用到代理的該URL上的參數(shù) |
Retry-After | 如果實體暫時不可取沉衣,通知客戶端在指定時間之后再次嘗試 |
Server | 指明服務器用于處理請求的軟件信息 |
Vary | 告訴下游代理是使用緩存響應還是從原始服務器請求 |
WWW-Authenticate | 表明客戶端請求實體應該使用的授權方案 |
參考資料
HTTP 2.0 協(xié)議詳解
一郁副、HTTP 2.0:改進傳輸性能
HTTP 2.0 的主要目標是改進傳輸性能,實現(xiàn)低延遲和高吞吐量豌习。從另一方面看存谎,HTTP 的高層協(xié)議語義并不會因為這次版本升級而受影響。所有HTTP 首部肥隆、值既荚,以及它們的使用場景都不會變。
現(xiàn)有的任何網(wǎng)站和應用栋艳,無需做任何修改都可以在HTTP 2.0 上跑起來恰聘。不用為了利用HTTP 2.0 的好處而修改標記。HTTP 服務器必須運行HTTP 2.0 協(xié)議吸占,但大部分用戶都不會因此而受到影響晴叨。
二、HTTP2.0歷史及其與SPDY的淵源
SPDY 是谷歌開發(fā)的一個實驗性協(xié)議矾屯,于2009 年年中發(fā)布兼蕊,主要目標是通過解決HTTP 1.1 中廣為人知的一些性能限制,來減少網(wǎng)頁的加載延遲
SPDY協(xié)議設定的目標
頁面加載時間(PLT件蚕,Page ? Load Time)降低 50%孙技;
無需網(wǎng)站作者修改任何內容惧所;
把部署復雜性降至最低,無需變更網(wǎng)絡基礎設施绪杏;
與開源社區(qū)合作開發(fā)這個新協(xié)議;
-
收集真實性能數(shù)據(jù)纽绍,驗證這個實驗性協(xié)議是否有效蕾久。
Alt text
注:為了達到降低50% 頁面加載時間的目標,SPDY 引入了一個新的二進制分幀數(shù)據(jù)層拌夏,以實現(xiàn)多向請求和響應僧著、優(yōu)先次序、最小化及消除不必要的網(wǎng)絡延遲障簿,目的是更有效地利用底層TCP 連接盹愚;
HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了議事日程,吸取SPDY 的經(jīng)驗教訓站故,并在此基礎上制定官方標準
三皆怕、HTTP2.0深入探究
HTTP/2.0 應該滿足如下條件:
- 相對于使用TCP 的HTTP 1.1,? 用戶在大多數(shù)情況下的感知延遲要有實質上西篓、可度量的改進愈腾;
- 解決 HTTP 中的“隊首阻塞”問題;
- 并行操作無需與服務器建立多個連接岂津,從而改進 TCP 的利用率虱黄,特別是擁塞控制方面;
- 保持 HTTP 1.1 的語義吮成,利用現(xiàn)有文檔橱乱,包括(但不限于)HTTP 方法、狀態(tài)碼粱甫、URI泳叠,以及首部字段;
- 明確規(guī)定 HTTP 2.0 如何與 HTTP 1.x 互操作茶宵,特別是在中間介質上析二;
- 明確指出所有新的可擴展機制以及適當?shù)臄U展策略。
HTTP 2.0 致力于突破上一代標準眾所周知的性能限制节预,但它也是對之前1.x 標準的擴展叶摄,而非替代。之所以要遞增一個大版本到2.0安拟,主要是因為它改變了客戶端與服務器之間交換數(shù)據(jù)的方式蛤吓,HTTP 2.0 增加了新的二進制分幀數(shù)據(jù)層
四、HTTP2.0設計和技術目標
HTTP/2.0 通過支持首部字段壓縮和在同一連接上發(fā)送多個并發(fā)消息糠赦,讓應用更有效地利用網(wǎng)絡資源会傲,減少感知的延遲時間锅棕。而且,它還支持服務器到客戶端的主動推送機制淌山。
-
二進制分幀層
- HTTP 2.0 二進制分幀層裸燎,封裝HTTP 消息并在客戶端與服務器之間傳輸
Alt textHTTP2.0 將所有傳輸?shù)男畔⒎指顬楦〉南⒑蛶λ鼈儾捎枚M制格式的編碼泼疑。
注:HTTPS 是二進制分幀的另一個典型示例:所有HTTP 消息都以透明的方式為我們編碼和解碼德绿,不必對應用進行任何修改。HTTP2.0工作原理有點類似
-
流退渗、消息和幀
- 流:流是連接中的一個虛擬信道移稳,可以承載雙向的消息;每個流都有一個唯一的整數(shù)標識符(1会油、2…N)个粱;
- 消息:是指邏輯上的 HTTP 消息,比如請求翻翩、響應等都许,由一或多個幀組成。
- 幀:HTTP 2.0 通信的最小單位嫂冻,每個幀包含幀首部梭稚,至少也會標識出當前幀所屬的流,承載著特定類型的數(shù)據(jù)絮吵,如 HTTP 首部弧烤、負荷,等等
Alt text- HTTP 2.0 的所有幀都采用二進制編碼蹬敲,所有首部數(shù)據(jù)都會被壓縮暇昂。
- 所有通信都在一個 TCP 連接上完成。
- HTTP 2.0 把HTTP協(xié)議通信的基本單位縮小為一個一個的幀伴嗡,這些幀對應著邏輯流中的消息急波。相應地,很多流可以并行地在同一個TCP 連接上交換消息
-
多向請求與響應
-
HTTP 2.0 中新的二進制分幀層突破了這些限制瘪校,實現(xiàn)了多向請求和響應:客戶端和服務器可以把HTTP 消息分解為互不依賴的幀澄暮,然后亂序發(fā)送,最后再在另一端把它們重新組合起來
Alt text 圖中包含了同一個連接上多個傳輸中的數(shù)據(jù)流:客戶端正在向服務器傳輸一個DATA 幀(stream 5)阱扬,與此同時泣懊,服務器正向客戶端亂序發(fā)送stream 1 和stream 3的一系列幀。此時麻惶,一個連接上有3 個請求/ 響應并行交換馍刮!
把HTTP 消息分解為獨立的幀,交錯發(fā)送窃蹋,然后在另一端重新組裝是HTTP 2.0 最重要的一項增強卡啰。這個機制會在整個Web 技術棧中引發(fā)一系列連鎖反應沦零,從而帶來巨大的性能提升惩阶。
* 可以并行交錯地發(fā)送請求作烟,請求之間互不影響球涛; * 可以并行交錯地發(fā)送響應,響應之間互不干擾亡脸; * 只使用一個連接即可并行發(fā)送多個請求和響應押搪; * 消除不必要的延遲,從而減少頁面加載的時間梗掰; * 不必再為繞過 HTTP 1.x 限制而多做很多工作;
- HTTP 2.0 的二進制分幀機制解決了HTTP 1.x 中存在的隊首阻塞問題嗅回,也消除了并行處理和發(fā)送請求及響應時對多個連接的依賴及穗。
-
-
請求優(yōu)先級
- 把HTTP 消息分解為很多獨立的幀之后,就可以通過優(yōu)化這些幀的交錯和傳輸順序绵载,每個流都可以帶有一個31 比特的優(yōu)先值:0 表示最高優(yōu)先級埂陆;2的31次方-1 表示最低優(yōu)先級。
- 服務器可以根據(jù)流的優(yōu)先級娃豹,控制資源分配(CPU焚虱、內存、帶寬)懂版,而在響應數(shù)據(jù)準備好之后鹃栽,優(yōu)先將最高優(yōu)先級的幀發(fā)送給客戶端。
- HTTP 2.0 一舉解決了所有這些低效的問題:瀏覽器可以在發(fā)現(xiàn)資源時立即分派請求躯畴,指定每個流的優(yōu)先級民鼓,讓服務器決定最優(yōu)的響應次序。這樣請求就不必排隊了蓬抄,既節(jié)省了時間丰嘉,也最大限度地利用了每個連接。
-
每個來源一個連接
-
有了新的分幀機制后嚷缭,HTTP 2.0 不再依賴多個TCP 連接去實現(xiàn)多流并行了饮亏。每個數(shù)據(jù)流都拆分成很多幀,而這些幀可以交錯阅爽,還可以分別優(yōu)先級路幸。HTTP 2.0 連接都是持久化的,而且客戶端與服務器之間也只需要一個連接即可付翁。
- 實驗表明劝赔,客戶端使用更少的連接肯定可以降低延遲時間。HTTP 2.0 發(fā)送的總分組數(shù)量比HTTP 差不多要少40%胆敞。
- 大多數(shù)HTTP 連接的時間都很短着帽,而且是突發(fā)性的杂伟,但TCP 只在長時間連接傳輸大塊數(shù)據(jù)時效率才最高。HTTP 2.0 通過讓所有數(shù)據(jù)流共用同一個連接仍翰,可以更有效地使用TCP 連接赫粥。
-
-
流量控制
-
HTTP 2.0 為數(shù)據(jù)流和連接的流量控制提供了一個簡單的機制:
- 流量控制基于每一跳進行,而非端到端的控制予借;
- 流量控制基于窗口更新幀進行越平,即接收方廣播自己準備接收某個數(shù)據(jù)流的多少字節(jié),以及對整個連接要接收多少字節(jié)灵迫;
- 流量控制窗口大小通過 WINDOW_UPDATE 幀更新秦叛,這個字段指定了流 ID 和窗口大小遞增值;
- 流量控制有方向性瀑粥,即接收方可能根據(jù)自己的情況為每個流乃至整個連接設置任意窗口大姓醢稀;
- 流量控制可以由接收方禁用狞换,包括針對個別的流和針對整個連接避咆。
-
-
服務器推送
-
HTTP 2.0 新增的一個強大的新功能,就是服務器可以對一個客戶端請求發(fā)送多個響應修噪。服務器向客戶端推送資源無需客戶端明確地請求查库。
Alt text HTTP 2.0 連接后,客戶端與服務器交換SETTINGS 幀黄琼,借此可以限定雙向并發(fā)的流的最大數(shù)量樊销。因此,客戶端可以限定推送流的數(shù)量脏款,或者通過把這個值設置為0 而完全禁用服務器推送现柠。
所有推送的資源都遵守同源策略。換句話說弛矛,服務器不能隨便將第三方資源推送給客戶端够吩,而必須是經(jīng)過雙方確認才行。
PUSH_PROMISE:所有服務器推送流都由PUSH_PROMISE 發(fā)端丈氓,服務器向客戶端發(fā)出的有意推送所述資源的信號周循。客戶端接收到PUSH_PROMISE 幀之后万俗,可以視自身需求選擇拒絕這個流
-
幾點限制:
- 服務器必須遵循請求- 響應的循環(huán)湾笛,只能借著對請求的響應推送資源
- PUSH_PROMISE 幀必須在返回響應之前發(fā)送,以免客戶端出現(xiàn)競態(tài)條件闰歪。
-
-
首部壓縮(HPACK壓縮算法嚎研,一邊用index mapping table壓縮,一邊編碼,這個table由靜態(tài)表和動態(tài)表組成)
http2.0會壓縮首部元數(shù)據(jù):在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發(fā)送的鍵值對临扮,對于相同的數(shù)據(jù)论矾,不再通過每次請求和響應發(fā)送;“首部表”在http2.0的連接存續(xù)期內始終存在杆勇,由客戶端和服務器共同漸進地更新贪壳;每個新的首部鍵值對要么追加到當前表的末尾,要么替換表中之前的值蚜退。
-
http2.0首部差異化傳輸
Alt text- 請求與響應首部的定義在HTTP2.0中基本沒有改變闰靴,只是所有首部鍵必須全部小寫,而且請求行要獨立為 :method钻注、:scheme蚂且、:host、:path這些鍵值對幅恋。
-
有效的HTTP2.0升級與發(fā)現(xiàn)
-
大多數(shù)現(xiàn)代瀏覽器都內置有高效的后臺升級機制杏死,支持HTTP2.0的客戶端在發(fā)起新請求之前,必須能發(fā)現(xiàn)服務器及所有中間設備是否支持HTTP2.0協(xié)議佳遣。有三種可能的情況:
- 通過TLS和ALPN發(fā)起新的HTTPS連接识埋;
- 根據(jù)之前的信息發(fā)起新的HTTP連接凡伊;
- 沒有之前的信息而發(fā)起新的HTTP連接零渐。
HTTPS 協(xié)商過程中有一個環(huán)節(jié)會使用ALPN(應用層協(xié)議協(xié)商)。減少網(wǎng)絡延遲是HTTP 2.0 的關鍵條件系忙,因此在建立HTTPS 連接時一定會用到ALPN協(xié)商诵盼。
通過常規(guī)非加密信道建立HTTP2.0連接需要多做一點工作。因為HTTP1.0和HTTP2.0都使用同一個端口(80)银还,有沒有服務器是否支持HTTP2.0的其他任何信息风宁,此時客戶端只能使用HTTP Upgrade機制通過協(xié)調確定適當?shù)膮f(xié)議:
Upgrade: HTTP/2.0 ? HTTP2-Settings: (SETTINGS payload) ? HTTP/1.1 200 OK ? HTTP/1.1 101 Switching Protocols ? ...
? 發(fā)起帶有HTTP 2.0 Upgrade 首部的HTTP 1.1 請求 ? HTTP/2.0 SETTINGS 凈荷的Base64 URL 編碼 ? 服務器拒絕升級,通過HTTP 1.1 返回響應 ? 服務器接受HTTP 2.0 升級蛹疯,切換到新分幀
-
HTTP2.0二進制分幀簡介
建立HTTP2.0連接后戒财,客戶端與服務器會通過交換幀來通信,幀是基于這個新協(xié)議通信的最小單位捺弦。所有幀都共享一個8字節(jié)的首部饮寞,其中包含幀的長度、類型列吼、標志幽崩,還有一個保留位和一個31位的流標識符。
-
發(fā)起新流
- 在發(fā)送應用數(shù)據(jù)之前寞钥,必須創(chuàng)建一個新流并隨之發(fā)送相應的元數(shù)據(jù)慌申,比如流優(yōu)先級、HTTP 首部等理郑;
- 客戶端通過發(fā)送HEADERS幀來發(fā)起新流蹄溉;
- 服務器通過發(fā)送 PUSH_PROMISE 幀來發(fā)起推送流咨油。
Alt text -
發(fā)送應用數(shù)據(jù)
- 創(chuàng)建新流并發(fā)送HTTP 首部之后,接下來就是利用DATA 幀类缤。應用數(shù)據(jù)可以分為多個DATA 幀臼勉,最后一幀要翻轉幀首部的END_STREAM 字段
Alt text- HTTP 2.0 標準要求DATA 幀不能超過2的14次方-1(16383)字節(jié)。長度超過這個閥值的數(shù)據(jù)餐弱,就得分幀發(fā)送宴霸。
-
HTTP2.0幀數(shù)據(jù)流分析
- HTTP2.0在共享的連接上同時發(fā)送請求和響應
Alt text- 3 個流的 ID 都是奇數(shù),說明都是客戶端發(fā)起的
- 服務器發(fā)送的 stream 1 包含多個 DATA 幀膏蚓,這是對客戶端之前請求的響應數(shù)據(jù)
- 服務器在交錯發(fā)送 stream 1 的 DATA 幀和 stream 3 的 HEADERS 幀瓢谢,這就是響應的多路復用!
- 客戶端正在發(fā)送 stream 5 的 DATA 幀驮瞧,表明 HEADERS 幀之前已經(jīng)發(fā)送過了氓扛。
針對HTTP2.0的優(yōu)化建議
-
去掉對1.x的優(yōu)化
- 每個來源使用一個連接,HTTP 2.0 通過將一個TCP 連接的吞吐量最大化來提升性能论笔。
- 去掉不必要的文件合并和圖片拼接:HTTP 2.0采郎,很多小資源都可以并行發(fā)送
- 利用服務器推送:之前針對HTTP 1.x 而嵌入的大多數(shù)資源,都可以而且應該通過服務器推送來交付狂魔。
-
雙協(xié)議應用策略
- 相同的應用代碼蒜埋,雙協(xié)議部署
- 分離應用代碼,雙協(xié)議部署
- 動態(tài)HTTP 1.x和HTTP 2.0優(yōu)化:某些自動化的Web 優(yōu)化框架在響應請求時動態(tài)重寫交付的應用代碼(包括連接最楷、拼合整份、分區(qū),等等)
- 單協(xié)議部署
-
1.x與2.0的相互轉換
Alt text -
評估服務器質量與性能
- HTTP 2.0 服務器必須理解流優(yōu)先級籽孙;
- HTTP 2.0 服務器必須根據(jù)優(yōu)先級處理響應和交付資源烈评;
- HTTP 2.0 服務器必須支持服務器推送;
- HTTP 2.0 服務器應該提供不同推送策略的實現(xiàn)犯建。
-
2.0與TLS
-
兩種可能出現(xiàn)ALPN 協(xié)商和TLS 終止的情況
- TLS 連接可能會在 HTTP 2.0 服務器上終止讲冠;
- TLS 連接可能會在上游(如負載均衡器)上終止。
第一種情況要求HTTP 2.0 服務器能夠處理TLS适瓦;
第二種情況建立一條加密信道竿开,直接將非加密的HTTP 2.0 流發(fā)送到服務器
Alt text -
-
負載均衡器、代理及應用服務器
- 要在TLS 之上實現(xiàn)HTTP 2.0通信犹菇,終端服務器必須支持 ALPN德迹;
- 盡可能在接近用戶的地方終止 TLS;
- 如果無法支持 ALPN揭芍,那么選擇 TCP 負載均衡模式胳搞;
- 如果無法支持 ALPN 且 TCP 負載均衡也做不到,那么就退而求其次,在非加密信道上使用HTTP 的Upgrade 流肌毅;
TCP/IP
TCP/IP是個協(xié)議組筷转,可分為三個層次:網(wǎng)絡層、傳輸層和應用層悬而。
在網(wǎng)絡層有IP協(xié)議呜舒、ICMP協(xié)議、ARP協(xié)議笨奠、RARP協(xié)議和BOOTP協(xié)議袭蝗。
在傳輸層中有TCP協(xié)議與UDP協(xié)議。
在應用層有:TCP包括FTP般婆、HTTP到腥、TELNET、SMTP等協(xié)議
UDP包括DNS蔚袍、TFTP等協(xié)議
短連接
連接->傳輸數(shù)據(jù)->關閉連接
HTTP是無狀態(tài)的乡范,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接啤咽,但任務結束就中斷連接晋辆。
也可以這樣說:短連接是指SOCKET連接后發(fā)送后接收完數(shù)據(jù)后馬上斷開連接。
長連接
連接->傳輸數(shù)據(jù)->保持連接 -> 傳輸數(shù)據(jù)-> 宇整。瓶佳。。 ->關閉連接没陡。
長連接指建立SOCKET連接后不管是否使用都保持連接涩哟,但安全性較差索赏。
http的長連接
HTTP也可以建立長連接的盼玄,使用Connection:keep-alive,HTTP 1.1默認進行持久連接潜腻。HTTP1.1和HTTP1.0相比較而言埃儿,最大的區(qū)別就是增加了持久連接支持(貌似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態(tài)的,或者說是不可以信任的融涣。
什么時候用長連接童番,短連接?
長連接多用于操作頻繁威鹿,點對點的通訊剃斧,而且連接數(shù)不能太多情況,忽你。每個TCP連接都需要三步握手幼东,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多根蟹,所以每個操作完后都不斷開脓杉,次處理時直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接简逮。例如:數(shù)據(jù)庫的連接用長連接球散, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創(chuàng)建也是對資源的浪費散庶。
而像WEB網(wǎng)站的http服務一般都用短鏈接蕉堰,因為長連接對于服務端來說會耗費一定的資源,而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源悲龟,如果用長連接嘁灯,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話躲舌,那可想而知吧丑婿。所以并發(fā)量大,但每個用戶無需頻繁操作情況下需用短連好没卸。
總之羹奉,長連接和短連接的選擇要視情況而定。
發(fā)送接收方式
1约计、異步
報文發(fā)送和接收是分開的诀拭,相互獨立的,互不影響煤蚌。這種方式又分兩種情況:
(1)異步雙工:接收和發(fā)送在同一個程序中耕挨,由兩個不同的子進程分別負責發(fā)送和接收
(2)異步單工:接收和發(fā)送是用兩個不同的程序來完成。
2尉桩、同步
報文發(fā)送和接收是同步進行筒占,既報文發(fā)送后等待接收返回報文。 同步方式一般需要考慮超時問題蜘犁,即報文發(fā)出去后不能無限等待翰苫,需要設定超時時間,超過該時間發(fā)送方不再等待讀返回報文这橙,直接通知超時返回奏窑。
在長連接中一般是沒有條件能夠判斷讀寫什么時候結束,所以必須要加長度報文頭屈扎。讀函數(shù)先是讀取報文頭的長度埃唯,再根據(jù)這個長度去讀相應長度的報文。
Socket是什么
Socket是應用層與TCP/IP協(xié)議族通信的中間軟件抽象層鹰晨,它是一組接口墨叛。在設計模式中滑沧,Socket其實就是一個門面模式,它把復雜的TCP/IP協(xié)議族隱藏在Socket接口后面巍实,對用戶來說滓技,一組簡單的接口就是全部,讓Socket去組織數(shù)據(jù)棚潦,以符合指定的協(xié)議令漂。
[圖片上傳失敗...(image-bfb4aa-1527588784406)]
通信過程:
[圖片上傳失敗...(image-90d03b-1527588784405)]
主機 A 的應用程序要能和主機 B 的應用程序通信,必須通過 Socket 建立連接丸边,而建立 Socket 連接必須需要底層 TCP/IP 協(xié)議來建立 TCP 連接叠必。建立 TCP 連接需要底層 IP 協(xié)議來尋址網(wǎng)絡中的主機。我們知道網(wǎng)絡層使用的 IP 協(xié)議可以幫助我們根據(jù) IP 地址來找到目標主機妹窖,但是一臺主機上可能運行著多個應用程序纬朝,如何才能與指定的應用程序通信就要通過 TCP 或 UPD 的地址也就是端口號來指定。這樣就可以通過一個 Socket 實例唯一代表一個主機上的一個應用程序的通信鏈路了骄呼。
建立通信鏈路
當客戶端要與服務端通信共苛,客戶端首先要創(chuàng)建一個 Socket 實例,操作系統(tǒng)將為這個 Socket 實例分配一個沒有被使用的本地端口號蜓萄,并創(chuàng)建一個包含本地和遠程地址和端口號的套接字數(shù)據(jù)結構隅茎,這個數(shù)據(jù)結構將一直保存在系統(tǒng)中直到這個連接關閉。在創(chuàng)建 Socket 實例的構造函數(shù)正確返回之前嫉沽,將要進行 TCP 的三次握手協(xié)議辟犀,TCP 握手協(xié)議完成后,Socket 實例對象將創(chuàng)建完成绸硕,否則將拋出 IOException 錯誤堂竟。
與之對應的服務端將創(chuàng)建一個 ServerSocket 實例,ServerSocket 創(chuàng)建比較簡單只要指定的端口號沒有被占用玻佩,一般實例創(chuàng)建都會成功出嘹,同時操作系統(tǒng)也會為 ServerSocket 實例創(chuàng)建一個底層數(shù)據(jù)結構,這個數(shù)據(jù)結構中包含指定監(jiān)聽的端口號和包含監(jiān)聽地址的通配符夺蛇,通常情況下都是“*”即監(jiān)聽所有地址疚漆。之后當調用 accept() 方法時酣胀,將進入阻塞狀態(tài)刁赦,等待客戶端的請求。當一個新的請求到來時闻镶,將為這個連接創(chuàng)建一個新的套接字數(shù)據(jù)結構甚脉,該套接字數(shù)據(jù)的信息包含的地址和端口信息正是請求源地址和端口。這個新創(chuàng)建的數(shù)據(jù)結構將會關聯(lián)到 ServerSocket 實例的一個未完成的連接數(shù)據(jù)結構列表中铆农,注意這時服務端與之對應的 Socket 實例并沒有完成創(chuàng)建牺氨,而要等到與客戶端的三次握手完成后狡耻,這個服務端的 Socket 實例才會返回,并將這個 Socket 實例對應的數(shù)據(jù)結構從未完成列表中移到已完成列表中猴凹。所以 ServerSocket 所關聯(lián)的列表中每個數(shù)據(jù)結構夷狰,都代表與一個客戶端的建立的 TCP 連接。
備注:
Windows 下單機最大TCP連接數(shù)
調整系統(tǒng)參數(shù)來調整單機的最大TCP連接數(shù)郊霎,Windows 下單機的TCP連接數(shù)有多個參數(shù)共同決定:
以下都是通過修改注冊表[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
**1.最大TCP連接數(shù) ** TcpNumConnections
2.TCP關閉延遲時間 TCPTimedWaitDelay (30-240)s
3.最大動態(tài)端口數(shù) MaxUserPort (Default = 5000, Max = 65534) TCP客戶端和服務器連接時沼头,客戶端必須分配一個動態(tài)端口,默認情況下這個動態(tài)端口的分配范圍為 1024-5000 书劝,也就是說默認情況下进倍,客戶端最多可以同時發(fā)起3977 Socket 連接
4.最大TCB 數(shù)量 MaxFreeTcbs
系統(tǒng)為每個TCP 連接分配一個TCP 控制塊(TCP control block or TCB),這個控制塊用于緩存TCP連接的一些參數(shù)购对,每個TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool猾昆,也就說,每個TCP連接會占用 1KB 的系統(tǒng)內存骡苞。
非Server版本垂蜗,MaxFreeTcbs 的默認值為1000 (64M 以上物理內存)Server 版本,這個的默認值為 2000解幽。也就是說么抗,默認情況下,Server 版本最多同時可以建立并保持2000個TCP 連接亚铁。
5. 最大TCB Hash table 數(shù)量 MaxHashTableSize TCB 是通過Hash table 來管理的蝇刀。
這個值指明分配 pagepool 內存的數(shù)量,也就是說徘溢,如果MaxFreeTcbs = 1000 , 則 pagepool 的內存數(shù)量為 500KB那么 MaxHashTableSize 應大于 500 才行吞琐。這個數(shù)量越大,則Hash table 的冗余度就越高然爆,每次分配和查找 TCP 連接用時就越少站粟。這個值必須是2的冪,且最大為65536.
IBM WebSphere Voice Server 在windows server 2003 下的典型配置
MaxUserPort = 65534 (Decimal)
MaxHashTableSize = 65536 (Decimal)
MaxFreeTcbs = 16000 (Decimal)
這里我們可以看到 MaxHashTableSize 被配置為比MaxFreeTcbs 大4倍曾雕,這樣可以大大增加TCP建立的速度
短連接和長連接
短連接:每次Http請求都會建立Tcp連接奴烙,管理容易
-
長連接:只需要建立一次Tcp連接,以后Http請求重復使用同一個Tcp連接剖张,管理難
這里寫圖片描述HTTP1.1規(guī)定了默認保持長連接(HTTP persistent connection 切诀,也有翻譯為持久連接),數(shù)據(jù)傳輸完成了保持TCP連接不斷開(不發(fā)RST包搔弄、不四次握手)幅虑,等待在同域名下繼續(xù)用這個通道傳輸數(shù)據(jù);相反的就是短連接
如果服務器沒有告訴客戶端超時時間也沒關系顾犹,服務端可能主動發(fā)起四次握手斷開TCP連接倒庵,客戶端能夠知道該TCP連接已經(jīng)無效褒墨;另外TCP還有心跳包來檢測當前連接是否還活著,方法很多擎宝,避免浪費資源郁妈。
在長連接的應用場景下,client端一般不會主動關閉它們之間的連接绍申,Client與server之間的連接如果一直不關閉的話圃庭,會存在一個問題,隨著客戶端連接越來越多失晴,server早晚有扛不住的時候剧腻,這時候server端需要采取一些策略,如關閉一些長時間沒有讀寫事件發(fā)生的連接涂屁,這樣可以避免一些惡意連接導致server端服務受損书在;如果條件再允許就可以以客戶端機器為顆粒度,限制每個客戶端的最大長連接數(shù)拆又,這樣可以完全避免某個蛋疼的客戶端連累后端服務儒旬。
長連接和短連接的產(chǎn)生在于client和server采取的關閉策略,具體的應用場景采用具體的策略帖族,沒有十全十美的選擇栈源,只有合適的選擇
應用場景區(qū)別:
- 一般長連接(追求實時性高的場景)用于少數(shù)client-end to server-end的頻繁的通信,例如:數(shù)據(jù)庫的連接用長連接竖般, 如果用短連接頻繁的通信會造成socket錯誤甚垦,而且頻繁的socket 創(chuàng)建也是對資源的浪費。
- 而像WEB網(wǎng)站的http服務一般都用短鏈接(追求資源易回收場景)涣雕,因為長連接對于服務端來說會耗費一定的資源艰亮,而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源。
短輪詢和長輪詢
和短連接和長連接有本質區(qū)別
1. 短輪詢:重復發(fā)送Http請求挣郭,查詢目標事件是否完成迄埃,優(yōu)點:編寫簡單,缺點:浪費帶寬和服務器資源
2. 長輪詢:在服務端hold住Http請求(死循環(huán)或者sleep等等方式)兑障,等到目標時間發(fā)生侄非,返回Http響應。優(yōu)點:在無消息的情況下不會頻繁的請求流译,缺點:編寫復雜