HTTP
HTTP連接管理
HTTP連接的過程
HTTP事務(wù)的時延
原因:
- 客戶端首先需要根據(jù)URI確定Web服務(wù)器的IP地址和端口號屹耐。
- 接下來参滴,客戶端會向服務(wù)器發(fā)送一條 TCP 連接請求, 并等待服務(wù)器回送一個請求接受應(yīng)答柒竞。
- 一旦連接建立起來了荔茬,客戶端就會通過新建立的 TCP 管道來發(fā)送 HTTP 請求。
- 最后旬薯,Web 服務(wù)器會回送 HTTP 響應(yīng)。
這些TCP網(wǎng)絡(luò)時延的大小取決于硬件速度零聚、網(wǎng)絡(luò)和服務(wù)器的負(fù)載,請求和響應(yīng)報文的尺寸些侍,以及客戶端和服務(wù)器之間的距離隶症。
TCP連接的握手時延
TCP連接的握手時延對應(yīng)于上圖的建立連接部分。發(fā)送任意數(shù)據(jù)岗宣,當(dāng)新建立一條TCP連接時蚂会,都會走一下如下握手過程。如果連接只用來傳送少量數(shù)據(jù)耗式,這些握手過程就會嚴(yán)重降低 HTTP 的性能胁住。
TCP 連接握手需要經(jīng)過以下幾個步驟:
- 請求新的 TCP 連接時, 客戶端要向服務(wù)器發(fā)送一個小的 TCP 分組( 通常是 40 ~60 個字節(jié))刊咳。 這個分組中設(shè)置了一個特殊的 SYN 標(biāo)記彪见,說明這是一個連接請求。(a部分)
- 如果服務(wù)器接受了連接娱挨,就會對一些連接參數(shù)進(jìn)行計算余指,并向客戶端回送一個TCP 分組,這個分組中的 SYN 和 ACK 標(biāo)記都被置位跷坝,說明連接請求已被接受酵镜。(b部分)
- 最后碉碉, 客戶端向服務(wù)器回送一條確認(rèn)信息, 通知它連接已成功建立(c部分)
TCP慢啟動
TCP 連接會隨著時間進(jìn)行自我“ 調(diào)諧”淮韭, 起初會限制連接的最大速度垢粮, 如果數(shù)據(jù)成功傳輸, 會隨著時間的推移提高傳輸?shù)乃俣取?這種調(diào)諧被稱為 TCP 慢啟動( slow start)靠粪, 用于防止因特網(wǎng)的突然過載和擁塞蜡吧。
??由于存在這種擁塞控制特性, 所以新連接的傳輸速度會比已經(jīng)交換過一定量數(shù)據(jù)的、“ 已調(diào)諧” 連接慢一些军援。
HTTP連接的處理
并行連接
??試想仗嗦,當(dāng)瀏覽器加載一個頁面時,如果一個個HTTP請求都串行執(zhí)行耀鸦,那顯示出這個頁面將會奇慢無比。
實際上啸澡,瀏覽器確實使用了并行連接,但它們會將并行連接的總數(shù)限制為一個較小的值(通常是4個)袖订。之前看baidu的webuploader的設(shè)計文檔,經(jīng)過測試嗅虏,當(dāng)文件分片上傳時洛姑,建議開始的線程為3個。持久連接
??HTTP/1.1(以及 HTTP/1.0 的各種增強版本)允許 HTTP 設(shè)備在事務(wù)處理結(jié)束之后將 TCP 連接保持在打開狀態(tài)皮服, 以便為未來的 HTTP 請求重用現(xiàn)存的連接楞艾。 在事務(wù)處理結(jié)束之后仍然保持在打開狀態(tài)的 TCP 連接被稱為持久連接。 非持久連接會在每個事務(wù)結(jié)束之后關(guān)閉龄广。持久連接會在不同事務(wù)之間保持打開狀態(tài)硫眯, 直到客戶端或服務(wù)器決定將其關(guān)閉為止。
??持久連接降低了時延和連接建立的開銷择同,將連接保持在已調(diào)諧狀態(tài)两入, 而且減少了打開連接的潛在數(shù)量。
HTTP 1.1
- 雖然 HTTP1.1 默認(rèn)是開啟 Keep-Alive 長連接的敲才,一定程度上彌補了HTTP1.0每次請求都要創(chuàng)建連接的缺點裹纳,但是依然存在 head of line blocking,如果出現(xiàn)一個較差的網(wǎng)絡(luò)請求紧武,會影響后續(xù)的網(wǎng)絡(luò)請求剃氧。為什么呢?如果你發(fā)出1阻星、2她我、3 三個網(wǎng)絡(luò)請求,那么 Response 的順序 2、3 要在第一個網(wǎng)絡(luò)請求之后番舆,以此類推
- 針對同一域名酝碳,在請求較多的情況下,HTTP1.1 會開辟多個連接恨狈,據(jù)說瀏覽器一般是6-8 個疏哗,較多連接也會導(dǎo)致延遲增大,資源消耗等問題
- HTTP1.1 不安全禾怠,可能存在被篡改返奉、被竊聽、被偽裝等問題吗氏。當(dāng)然芽偏,前陣子 Apple 推廣 HTTPS 的時候,相信很多人已經(jīng)接入 HTTPS
- HTTP 的頭部沒有壓縮弦讽,header 的大小也是傳輸?shù)呢?fù)擔(dān)污尉,帶來更多的流量消耗和傳輸延遲。并且很多 header 是相同的往产,重復(fù)傳輸是沒有必要的被碗。
- 服務(wù)端無法主動推送資源到客戶端
- HTTP1.1的格式是文本格式,基于文本做一些擴(kuò)展仿村、優(yōu)化相對比較困難锐朴,但是文本格式易于閱讀和調(diào)試,但HTTPS之后蔼囊,也變成二進(jìn)制格式了焚志,這個優(yōu)勢也不復(fù)存在
HTTP2.0
在 HTTP2.0中,上面的問題幾乎都不存在了畏鼓。HTTP2.0 的設(shè)計來源于 Google 的 SPDY 協(xié)議酱酬,如果對 SPDY 協(xié)議不了解的話,也可以先對 SPDY 進(jìn)行了解滴肿,不過這不影響繼續(xù)閱讀本文
-
HTTP 2.0 使用新的二進(jìn)制格式:基本的協(xié)議單位是幀岳悟,每個幀都有不同的類型和用途佃迄,規(guī)范中定義了10種不同的幀泼差。例如,報頭(HEADERS)和數(shù)據(jù)(DATA)幀組成了基本的HTTP 請求和響應(yīng)呵俏;其他幀例如 設(shè)置(SETTINGS),窗口更新(WINDOW_UPDATE), 和推送承諾(PUSH_PROMISE)是用來實現(xiàn)HTTP/2的其他功能堆缘。那些請求和響應(yīng)的幀數(shù)據(jù)通過流來進(jìn)行數(shù)據(jù)交換。新的二進(jìn)制格式是流量控制普碎、優(yōu)先級吼肥、server push等功能的基礎(chǔ)
流(Stream):一個Stream是包含一條或多條信息、ID和優(yōu)先級的雙向通道
消息(Message):消息由幀組成
幀(Frame):幀有不同的類型,并且是混合的缀皱。他們通過stream id被重新組裝進(jìn)消息中 -
多路復(fù)用:也就是連接共享斗这,剛才說到 HTTP1.1的 head of line blocking,那么在多路復(fù)用的情況下啤斗,blocking 已經(jīng)不存在了表箭。每個連接中 可以包含多個流,而每個流中交錯包含著來自兩端的幀钮莲。也就是說同一個連接中是來自不同流的數(shù)據(jù)包混合在一起免钻,如下圖所示,每一塊代表幀崔拥,而相同顏色塊來自同一個流极舔,每個流都有自己的 ID,在接收端會根據(jù) ID 進(jìn)行重裝組合链瓦,就是通過這樣一種方式來實現(xiàn)多路復(fù)用拆魏。
1493090476519843.png 單一連接:剛才也說到 1.1 在請求多的時候,會開啟6-8個連接澡绩,而 HTTP2 只會開啟一個連接稽揭,這樣就減少握手帶來的延遲。
頭部壓縮:HTTP2.0 通過 HPACK 格式來壓縮頭部肥卡,使用了哈夫曼編碼壓縮溪掀、索引表來對頭部大小做優(yōu)化。索引表是把字符串和數(shù)字之間做一個匹配步鉴,比如method: GET對應(yīng)索引表中的2揪胃,那么如果之前發(fā)送過這個值是,就會緩存起來氛琢,之后使用時發(fā)現(xiàn)之前發(fā)送過該Header字段喊递,并且值相同,就會沿用之前的索引來指代那個Header值阳似。
Server Push:就是服務(wù)端可以主動推送一些東西給客戶端骚勘,也被稱為緩存推送。推送的資源可以備客戶端日后之需撮奏,需要的時候直接拿出來用俏讹,提升了速率。具體的實驗可以參考這里:iOS HTTP/2 Server Push 探索
Socket
Socket原理
套接字(socket)
套接字(socket)是通信的基石畜吊,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元泽疆。它是網(wǎng)絡(luò)通信過程中端點的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議玲献,本地主機(jī)的IP地址殉疼,本地進(jìn)程的協(xié)議端口梯浪,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口瓢娜。
應(yīng)用層通過傳輸層進(jìn)行數(shù)據(jù)通信時挂洛,TCP會遇到同時為多個應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問題。多個TCP連接或多個應(yīng)用程序進(jìn)程可能需要通過同一個 TCP協(xié)議端口傳輸數(shù)據(jù)眠砾。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接抹锄,許多計算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng)用層可以和傳輸層通過Socket接口荠藤,區(qū)分來自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信伙单,實現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。
建立socket連接
建立Socket連接至少需要一對套接字哈肖,其中一個運行于客戶端吻育,稱為ClientSocket ,另一個運行于服務(wù)器端淤井,稱為ServerSocket ;
套接字之間的連接過程分為三個步驟:服務(wù)器監(jiān)聽布疼,客戶端請求,連接確認(rèn)币狠。
- 服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字游两,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡(luò)狀態(tài)漩绵,等待客戶端的連接請求贱案。
- 客戶端請求:指客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字止吐。為此宝踪,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號碍扔,然后就向服務(wù)器端套接字提出連接請求瘩燥。
- 連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求時,就響應(yīng)客戶端套接字的請求不同,建立一個新的線程厉膀,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述二拐,雙方就正式建立連接服鹅。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求卓鹿。
SOCKET連接與TCP連接
創(chuàng)建Socket連接時菱魔,可以指定使用的傳輸層協(xié)議留荔,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP)吟孙,當(dāng)使用TCP協(xié)議進(jìn)行連接時澜倦,該Socket連接就是一個TCP連接。
Socket連接與HTTP連接
由于通常情況下Socket連接就是TCP連接杰妓,因此Socket連接一旦建立藻治,通信雙方即可開始相互發(fā)送數(shù)據(jù)內(nèi)容,直到雙方連接斷開巷挥。但在實際網(wǎng)絡(luò)應(yīng)用中桩卵,客戶端到服務(wù)器之間的通信往往需要穿越多個中間節(jié)點,例如路由器倍宾、網(wǎng)關(guān)雏节、防火墻等,大部分防火墻默認(rèn)會關(guān)閉長時間處于非活躍狀態(tài)的連接而導(dǎo)致 Socket 連接斷連高职,因此需要通過輪詢告訴網(wǎng)絡(luò)钩乍,該連接處于活躍狀態(tài)。
而HTTP連接使用的是“請求—響應(yīng)”的方式怔锌,不僅在請求時需要先建立連接寥粹,而且需要客戶端向服務(wù)器發(fā)出請求后,服務(wù)器端才能回復(fù)數(shù)據(jù)埃元。
很多情況下涝涤,需要服務(wù)器端主動向客戶端推送數(shù)據(jù),保持客戶端與服務(wù)器數(shù)據(jù)的實時與同步岛杀。此時若雙方建立的是Socket連接阔拳,服務(wù)器就可以直接將數(shù)據(jù)傳送給客戶端;若雙方建立的是HTTP連接类嗤,則服務(wù)器需要等到客戶端發(fā)送一次請求后才能將數(shù)據(jù)傳回給客戶端衫生,因此,客戶端定時向服務(wù)器端發(fā)送連接請求土浸,不僅可以保持在線罪针,同時也是在“詢問”服務(wù)器是否有新的數(shù)據(jù),如果有就將數(shù)據(jù)傳給客戶端黄伊。
區(qū)別簡述:
1)http是一種協(xié)議泪酱,socket是一種編程接口,主要包括TCP協(xié)議和UDP協(xié)議;
2)http和TCP/UDP是兩個不同層上的的協(xié)議还最。http是應(yīng)用層的協(xié)議墓阀,TCP/UDP是傳輸層的協(xié)議,http是在TCP/UDP之上的協(xié)議拓轻,http協(xié)議使用了TCP/UDP,http更加高級一點但是沒有很好的靈活性斯撮。也就是http使用起來比TCP/UDP要簡單,只需要遵循規(guī)范就可以進(jìn)行網(wǎng)絡(luò)通信了扶叉。