一、HTTP
HTTP協(xié)議是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的應(yīng)用層協(xié)議,萬(wàn)維網(wǎng)都要遵守HTTP協(xié)議。
HTTP/1.0
HTTP/1.0版本實(shí)現(xiàn)了HTTP協(xié)議的基本功能,但是1.0版本性能問(wèn)題比較明顯,因?yàn)镠TTP協(xié)議是基于TCP協(xié)議的,所以HTTP的性能問(wèn)題大多數(shù)都來(lái)自于TCP協(xié)議,在每次使用HTTP協(xié)議傳輸數(shù)據(jù)之前都要先建立TCP連接,建立TCP連接要進(jìn)行三次握手,并且TCP的慢啟動(dòng)機(jī)制使新建立的TCP連接的傳輸速率比較慢,當(dāng)HTTP請(qǐng)求量增大時(shí),HTTP協(xié)議的性能問(wèn)題就出現(xiàn)了。
HTTP/1.1
- HTTP/1.1版本默認(rèn)開(kāi)啟了長(zhǎng)連接,客戶端可以復(fù)用之前的TCP連接請(qǐng)求服務(wù)器,減少了建立TCP連接和TCP慢啟動(dòng)的時(shí)間。在HTTP請(qǐng)求比較多,網(wǎng)絡(luò)情況不好時(shí),長(zhǎng)連接可能會(huì)發(fā)生隊(duì)頭阻塞,所以在長(zhǎng)連接的基礎(chǔ)上,HTTP/1.1還支持管道化模式,解決了請(qǐng)求隊(duì)頭阻塞的情況,但是在接受響應(yīng)時(shí)還是可能造成隊(duì)頭阻塞。
- HTTP/1.1頭部信息增加HOST字段,一臺(tái)物理服務(wù)器上可以存在多個(gè)虛擬主機(jī),并且它們共享一個(gè)IP地址,HTTP/1.1的請(qǐng)求頭和響應(yīng)頭都應(yīng)該添加HOST字段。
- HTTP/1.1添加和100響應(yīng)碼,HTTP協(xié)議請(qǐng)求會(huì)先發(fā)送頭部信息,如果服務(wù)器返回100響應(yīng)碼,再將請(qǐng)求體發(fā)送到服務(wù)器,如果返回401響應(yīng)碼,放棄發(fā)送響應(yīng)體,節(jié)約帶寬。
- HTTP/1.1引入了Chunked transfer-coding機(jī)制,發(fā)送方將消息分割成若干個(gè)任意大小的數(shù)據(jù)塊,每個(gè)數(shù)據(jù)塊在發(fā)送時(shí)都會(huì)附上塊的長(zhǎng)度,最后用一個(gè)零長(zhǎng)度的塊作為消息結(jié)束的標(biāo)志。這種方法允許發(fā)送方只緩沖消息的一個(gè)片段,避免緩沖整個(gè)消息帶來(lái)的過(guò)載,利用Chunked transfer-coding機(jī)制可以實(shí)現(xiàn)斷點(diǎn)續(xù)傳。
- HTTP/1.1更新了緩存的處理機(jī)制,添加了AGE頭部表示緩存的有效期。
HTTPS
HTTPS協(xié)議是HTTP協(xié)議的安全版本,在HTTP協(xié)議和TCP協(xié)議之前添加了SSL/TSL協(xié)議,在TCP握手之后進(jìn)行SSL/TSL握手。

HTTP/2: HTTP/2是基于HTTPS的,HTTP/2相對(duì)于HTTP/1.x更專注于性能,相對(duì)于HTTP/1.x做了許多性能上的優(yōu)化:二進(jìn)制傳輸,多路復(fù)用,Heard壓縮,服務(wù)器推送,安全
1. 二進(jìn)制傳輸
明文傳輸不安全。HTTP/1使用明文傳輸,不安全。那么HTTP/2就用二進(jìn)制分幀層來(lái)解決這個(gè)問(wèn)題,幀是數(shù)據(jù)傳輸?shù)淖钚挝唬远M(jìn)制傳輸代替原本的明文傳輸,原本的報(bào)文消息被劃分為更小的數(shù)據(jù)幀。
2. 多路復(fù)用
HTTP/2采用了多路復(fù)用技術(shù),在一個(gè) TCP 連接上,我們可以向?qū)Ψ讲粩喟l(fā)送幀,每幀的stream_id標(biāo)明這一幀屬于哪個(gè)流,然后在對(duì)方接收時(shí),根據(jù) stream_id拼接每個(gè)流的所有幀組成一整塊數(shù)據(jù)。把 HTTP/1.1 每個(gè)請(qǐng)求都當(dāng)作一個(gè)流,那么多個(gè)請(qǐng)求變成多個(gè)流,請(qǐng)求響應(yīng)數(shù)據(jù)分成多個(gè)幀,不同流中的幀交錯(cuò)地發(fā)送給對(duì)方,這就是 HTTP/2 中的多路復(fù)用。同時(shí)呢,我們知道HTTP/1的body長(zhǎng)度是在header帶過(guò)來(lái)的,那么如果是以HTTP/2 的形式去傳輸肯定會(huì)出問(wèn)題,所以HTTP/2 將body加上了length字段,每一個(gè)流都有自己的長(zhǎng)度,最后根據(jù)流的頭部長(zhǎng)度是否等于各個(gè)流的長(zhǎng)度來(lái)確定是否合包。同時(shí)呢,這樣分包合包也解決了線頭阻塞的問(wèn)題。TCP會(huì)保證包的有序性且保證了包不會(huì)丟失。
3. Heard壓縮
Header 內(nèi)容多,而且每次請(qǐng)求 Header 不會(huì)變化太多,沒(méi)有相應(yīng)的壓縮傳輸優(yōu)化方案。HTTP/2在此用hpack算法來(lái)壓縮首部長(zhǎng)度,其原理就是維護(hù)一個(gè)靜態(tài)索引表和動(dòng)態(tài)索引表的索引空間,hpack其原理就是匹配當(dāng)前連接存在的索引空間,若某個(gè)鍵值已存在,則用相應(yīng)的索引代替首部條目,比如 “:method: GET” 可以匹配到靜態(tài)索引中的 index 2,傳輸時(shí)只需要傳輸一個(gè)包含 2 的字節(jié)即可;若索引空間中不存在,則用字符編碼傳輸,字符編碼可以選擇哈夫曼編碼,然后分情況判斷是否需要存入動(dòng)態(tài)索引表中,以這種形式節(jié)省了很多的空間。
4. 服務(wù)器推送
為了盡可能減少請(qǐng)求數(shù),需要做合并文件、雪碧圖、資源內(nèi)聯(lián)等優(yōu)化工作,但是這無(wú)疑造成了單個(gè)請(qǐng)求內(nèi)容變大延遲變高的問(wèn)題,且內(nèi)嵌的資源不能有效地使用緩存機(jī)制。對(duì)于這種情況,HTTP/2推出了服務(wù)端推送,瀏覽器發(fā)送一個(gè)請(qǐng)求,服務(wù)器主動(dòng)向?yàn)g覽器推送與這個(gè)請(qǐng)求相關(guān)的資源,這樣瀏覽器就不用發(fā)起后續(xù)請(qǐng)求,其主要是針對(duì)資源內(nèi)聯(lián)做出的優(yōu)化。 ##QUIC新功能(HTTP/3): ###1. 0-RTT建連: 通過(guò)使用類似 TCP 快速打開(kāi)的技術(shù),緩存當(dāng)前會(huì)話的上下文,在下次恢復(fù)會(huì)話的時(shí)候,只需要將之前的緩存?zhèn)鬟f給服務(wù)端驗(yàn)證通過(guò)就可以進(jìn)行傳輸了。 ###2. 多路復(fù)用: 雖然 HTTP/2 支持了多路復(fù)用,但是 TCP 協(xié)議終究是沒(méi)有這個(gè)功能的。QUIC 原生就實(shí)現(xiàn)了這個(gè)功能,并且傳輸?shù)膯蝹€(gè)數(shù)據(jù)流可以保證有序交付且不會(huì)影響其他的數(shù)據(jù)流,這樣的技術(shù)就解決了之前 TCP 存在的問(wèn)題 ###3. 加密認(rèn)證的報(bào)文: 報(bào)文頭部都是經(jīng)過(guò)認(rèn)證的,報(bào)文 Body 都是經(jīng)過(guò)加密的 ###4. 向前糾錯(cuò)機(jī)制: 每個(gè)數(shù)據(jù)包除了它本身的內(nèi)容之外,還包括了部分其他數(shù)據(jù)包的數(shù)據(jù),因此少量的丟包可以通過(guò)其他包的冗余數(shù)據(jù)直接組裝而無(wú)需重傳,這種技術(shù)只能使用在丟失一個(gè)包的情況下,如果出現(xiàn)丟失多個(gè)包就不能使用糾錯(cuò)機(jī)制了,只能使用重傳的方式了。
HTTP緩存機(jī)制
1.強(qiáng)緩存
緩存規(guī)則信息包含在header中,而強(qiáng)緩存的規(guī)則通常由Expires和Cache-Control這兩個(gè)字段標(biāo)明
Expire
Expires表示到期時(shí)間,一般在Response的header中標(biāo)識(shí),當(dāng)?shù)诙握?qǐng)求時(shí)間超過(guò)此時(shí)間,則判定為緩存過(guò)期,需重新向服務(wù)器請(qǐng)求數(shù)據(jù),否則直接返回緩存數(shù)據(jù)。這個(gè)字段存在的問(wèn)題是這個(gè)時(shí)間是由服務(wù)器返回的時(shí)間,如果客戶端和服務(wù)端時(shí)間存在誤差,則會(huì)造成緩存機(jī)制的誤差。
Expires: Thu, 13 Sep 2018 02:08:54 GMT
Cache-Control Cache-Control標(biāo)明緩存的持續(xù)時(shí)間,是一個(gè)相對(duì)值,比如max-age= 604800,表示緩存有效期可以持續(xù)604800秒即一周,在一周內(nèi)再次請(qǐng)求這條數(shù)據(jù),直接返回緩存數(shù)據(jù)。Cache-Control常用取值有private、public、no-cache、max-age,no-store
- max-age:即上面提到的表明緩存的持續(xù)時(shí)間;
- private:表示客戶端可以緩存數(shù)據(jù),默認(rèn)為private;
- public:表示所有內(nèi)容都將被緩存,客戶端和代理服務(wù)器都可緩存;
- no-cache:字段表示客戶端需驗(yàn)證服務(wù)器響應(yīng)是否有更改(即下面說(shuō)到的對(duì)比緩存);
- no-store:不允許緩存
Cache-Control: private, max-age=0, no-cache
2.協(xié)商緩存
與強(qiáng)制緩存不同的是,協(xié)商緩存每次進(jìn)行再請(qǐng)求時(shí),需要先向服務(wù)器查詢?cè)摼彺媸欠窨捎茫绻彺婵捎茫瑒t返回304狀態(tài)碼,通知客戶端可以使用緩存,否則響應(yīng)整片資源內(nèi)容。協(xié)商緩存有這幾個(gè)字段來(lái)標(biāo)識(shí)緩存規(guī)則:Last-Modified / If-Modified-Since 、Etag / If-None-Match
Last-Modified / If-Modified-Since
服務(wù)器在響應(yīng)客戶端請(qǐng)求時(shí),頭部通過(guò)Last-Modified 告訴客戶端資源的最后修改時(shí)間,客戶端再次請(qǐng)求時(shí),頭部字段攜帶If-Modified-Since告訴服務(wù)器,上次返回的資源最后修改時(shí)間,讓服務(wù)器進(jìn)行對(duì)比,若當(dāng)前資源最后修改時(shí)間大于If-Modified-Since,則說(shuō)明資源被改動(dòng)了,響應(yīng)整片資源,返回200狀態(tài)碼,否則返回304狀態(tài)碼,通知客戶端可以使用緩存。
Etag / If-None-Match
etag是服務(wù)器對(duì)資源的一種摘要,客戶端請(qǐng)求時(shí),返回響應(yīng)中該字段告訴客戶端緩存數(shù)據(jù)的標(biāo)識(shí)。客戶端再次請(qǐng)求通過(guò)If-None-Match與服務(wù)器匹配,匹配成功說(shuō)明緩存可用,返回304,若服務(wù)端對(duì)數(shù)據(jù)發(fā)生更改,則匹配不成功,重新響應(yīng)資源和緩存規(guī)則信息(優(yōu)先級(jí)大于Last-Modified / If-Modified-Since)。 ###3.緩存機(jī)制總結(jié)

WebSocket
WebSocket本質(zhì)上一種計(jì)算機(jī)網(wǎng)絡(luò)應(yīng)用層的協(xié)議
WebSocket和HTTP相同點(diǎn)
- 都是基于TCP的應(yīng)用層協(xié)議。
- 都使用Request/Response模型進(jìn)行連接的建立。
- 在連接的建立過(guò)程中對(duì)錯(cuò)誤的處理方式相同,在這個(gè)階段WebSocket可能返回和HTTP相同的返回碼。
- 都可以在網(wǎng)絡(luò)中傳輸數(shù)據(jù)。
WebSocket和HTTP不同點(diǎn)
- WebSocket使用HTTP來(lái)建立連接,但是定義了一系列新的header域,這些域在HTTP中并不會(huì)使用。
- WebSocket的連接不能通過(guò)中間人來(lái)轉(zhuǎn)發(fā),它必須是一個(gè)直接連接。
- WebSocket連接建立之后,通信雙方都可以在任何時(shí)刻向另一方發(fā)送數(shù)據(jù)。
- WebSocket連接建立之后,數(shù)據(jù)的傳輸使用幀來(lái)傳遞,不再需要Request消息。
- WebSocket的數(shù)據(jù)幀有序。 ##使用WebSocket,而不是用Socket的原因: 因?yàn)檎麄€(gè)瀏覽器都不支持直接調(diào)用系統(tǒng)底層的 Socket,基于瀏覽器的 Web 自然無(wú)法調(diào)用,只能使用封裝的高級(jí)協(xié)議方案 —— WebSocket
最后
如果你看到了這里,覺(jué)得文章寫(xiě)得不錯(cuò)就給個(gè)贊唄!歡迎大家評(píng)論討論!如果你覺(jué)得那里值得改進(jìn)的,請(qǐng)給我留言。一定會(huì)認(rèn)真查詢,修正不足,定期免費(fèi)分享技術(shù)干貨。喜歡的小伙伴可以關(guān)注一下哦。謝謝!