與各大瀏覽器“強推”HTTPS 的待遇不一樣,HTTP/2 的公布可謂是“波瀾不驚”窿祥。雖然它是 HTTP 協(xié)議的一個重大升級株憾,但 Apple、Google 等科技巨頭并沒有像 HTTPS 那樣給予大量資源的支持。
直到今天嗤瞎,HTTP/2 在互聯(lián)網(wǎng)上還是處于“不溫不火”的狀態(tài)墙歪,雖然已經(jīng)有了不少的網(wǎng)站改造升級到了 HTTP/2,但普及的速度遠(yuǎn)不及 HTTPS贝奇。
所以虹菲,你有這樣的疑問也是很自然的,升級到 HTTP/2 究竟能給我們帶來多少好處呢掉瞳?到底“值不值”呢毕源?
** HTTP/2 的優(yōu)點 **
前面的幾講主要關(guān)注了 HTTP/2 的內(nèi)部實現(xiàn),今天我們就來看看它有哪些優(yōu)點和缺點陕习。
首先要說的是霎褐,HTTP/2 最大的一個優(yōu)點是?完全保持了與 HTTP/1 的兼容,在語義上沒有任何變化该镣,之前在 HTTP 上的所有投入都不會浪費冻璃。
因為兼容 HTTP/1,所以 HTTP/2 也具有 HTTP/1 的所有優(yōu)點损合,并且“基本”解決了 HTTP/1 的所有缺點省艳,安全與性能兼顧,可以認(rèn)為是“更安全的 HTTP嫁审、更快的 HTTPS”跋炕。
在安全上,HTTP/2 對 HTTPS 在各方面都做了強化律适。下層的 TLS 至少是 1.2枣购,而且只能使用前向安全的密碼套件(即 ECDHE),這同時也就默認(rèn)實現(xiàn)了“TLS False Start”擦耀,支持 1-RTT 握手,所以不需要再加額外的配置就可以自動實現(xiàn) HTTPS 加速
安全有了保障涩堤,再來看 HTTP/2 在性能方面的改進
你應(yīng)該知道眷蜓,影響網(wǎng)絡(luò)速度的兩個關(guān)鍵因素是“帶寬”和“延遲”,HTTP/2 的頭部壓縮胎围、多路復(fù)用吁系、流優(yōu)先級、服務(wù)器推送等手段其實都是針對這兩個要點白魂。
所謂的“帶寬”就是網(wǎng)絡(luò)的傳輸速度汽纤。從最早的 56K/s,到如今的 100M/s福荸,雖然網(wǎng)速已經(jīng)是“今非昔比”蕴坪,比從前快了幾十倍、幾百倍,但仍然是“稀缺資源”背传,圖片呆瞻、視頻這樣的多媒體數(shù)據(jù)很容易會把帶寬用盡。
節(jié)約帶寬的基本手段就是壓縮径玖,在 HTTP/1 里只能壓縮 body痴脾,而 HTTP/2 則可以用 HPACK 算法壓縮 header,這對高流量的網(wǎng)站非常有價值梳星,有數(shù)據(jù)表明能節(jié)省大概 5%~10% 的流量赞赖,這是實實在在的“真金白銀”。
與 HTTP/1“并發(fā)多個連接”不同冤灾,HTTP/2 的“多路復(fù)用”特性要求對一個域名(或者 IP)只用一個 TCP 連接前域,所有的數(shù)據(jù)都在這一個連接上傳輸,這樣不僅節(jié)約了客戶端瞳购、服務(wù)器和網(wǎng)絡(luò)的資源话侄,還可以把帶寬跑滿,讓 TCP 充分“吃飽”学赛。
這是為什么呢年堆?
我們來看一下在 HTTP/1 里的長連接,雖然是雙向通信盏浇,但任意一個時間點實際上還是單向的:上行請求時下行空閑变丧,下行響應(yīng)時上行空閑,再加上“隊頭阻塞”绢掰,實際的帶寬打了個“對折”還不止
而在 HTTP/2 里痒蓬,“多路復(fù)用”則讓 TCP 開足了馬力,“全速狂奔”滴劲,多個請求響應(yīng)并發(fā)攻晒,每時每刻上下行方向上都有流在傳輸數(shù)據(jù),沒有空閑的時候班挖,帶寬的利用率能夠接近 100%鲁捏。所以,HTTP/2 只使用一個連接萧芙,就能抵得過 HTTP/1 里的五六個連接给梅。
不過流也可能會有依賴關(guān)系,可能會存在等待導(dǎo)致的阻塞双揪,這就是“延遲”动羽,所以 HTTP/2 的其他特性就派上了用場。
“優(yōu)先級”可以讓客戶端告訴服務(wù)器渔期,哪個文件更重要运吓,更需要優(yōu)先傳輸,服務(wù)器就可以調(diào)高流的優(yōu)先級,合理地分配有限的帶寬資源羽德,讓高優(yōu)先級的 HTML几莽、圖片更快地到達(dá)客戶端,盡早加載顯示宅静。
“服務(wù)器推送”也是降低延遲的有效手段章蚣,它不需要客戶端預(yù)先請求,服務(wù)器直接就發(fā)給客戶端姨夹,這就省去了客戶端解析 HTML 再請求的時間纤垂。
** HTTP/2 的缺點 **
說了一大堆 HTTP/2 的優(yōu)點,再來看看它有什么缺點吧磷账。
聽過上一講 HTTP/3 的介紹峭沦,你就知道 HTTP/2 在 TCP 級別還是存在“隊頭阻塞”的問題。所以逃糟,如果網(wǎng)絡(luò)連接質(zhì)量差吼鱼,發(fā)生丟包,那么 TCP 會等待重傳绰咽,傳輸速度就會降低菇肃。
另外,在移動網(wǎng)絡(luò)中發(fā)生 IP 地址切換的時候取募,下層的 TCP 必須重新建連琐谤,要再次“握手”,經(jīng)歷“慢啟動”玩敏,而且之前連接里積累的 HPACK 字典也都消失了斗忌,必須重頭開始計算,導(dǎo)致帶寬浪費和時延旺聚。
剛才也說了织阳,HTTP/2 對一個域名只開一個連接,所以一旦這個連接出問題砰粹,那么整個網(wǎng)站的體驗也就變差了陈哑。
而這些情況下 HTTP/1 反而不會受到影響,因為它“本來就慢”伸眶,而且還會對一個域名開 6~8 個連接,頂多其中的一兩個連接會“更慢”刽宪,其他的連接不會受到影響厘贼。
** 應(yīng)該遷移到 HTTP/2 嗎?**
說到這里圣拄,你對遷移到 HTTP/2 是否已經(jīng)有了自己的判斷呢嘴秸?
在我看來,HTTP/2 處于一個略“尷尬”的位置,前面有“老前輩”HTTP/1岳掐,后面有“新來者”HTTP/3凭疮,即有“老前輩”的“打壓”,又有“新來者”的“追趕”串述,也就難怪沒有獲得市場的大力“吹捧”了执解。
但這絕不是說 HTTP/2“一無是處”,實際上 HTTP/2 的性能改進效果是非常明顯的纲酗,Top 1000 的網(wǎng)站中已經(jīng)有超過 40% 運行在了 HTTP/2 上衰腌,包括知名的 Apple、Facebook觅赊、Google右蕊、Twitter 等等。僅用了四年的時間吮螺,HTTP/2 就擁有了這么大的市場份額和巨頭的認(rèn)可饶囚,足以證明它的價值。
因為 HTTP/2 的側(cè)重點是“性能”鸠补,所以“是否遷移”就需要在這方面進行評估萝风。如果網(wǎng)站的流量很大,那么 HTTP/2 就可以帶來可觀的收益莫鸭;反之闹丐,如果網(wǎng)站流量比較小,那么升級到 HTTP/2 就沒有太多必要了被因,只要利用現(xiàn)有的 HTTP 再優(yōu)化就足矣卿拴。
不過如果你是新建網(wǎng)站,我覺得完全可以跳過 HTTP/1梨与、HTTPS堕花,直接“一步到位”,上 HTTP/2粥鞋,這樣不僅可以獲得性能提升缘挽,還免去了老舊的“歷史包袱”,日后也不會再有遷移的煩惱呻粹。
順便再多嘴一句壕曼,HTTP/2 畢竟是“下一代”HTTP 協(xié)議,它的很多特性也延續(xù)到了 HTTP/3等浊,提早升級到 HTTP/2 還可以讓你在 HTTP/3 到來時有更多的技術(shù)積累和儲備腮郊,不至于落后于時代。
** 配置 HTTP/2 **
假設(shè)你已經(jīng)決定要使用 HTTP/2筹燕,應(yīng)該如何搭建服務(wù)呢轧飞?
因為 HTTP/2“事實上”是加密的衅鹿,所以如果你已經(jīng)在“安全篇”里成功遷移到了 HTTPS,那么在 Nginx 里啟用 HTTP/2 簡直可以說是“不費吹灰之力”过咬,只需要在 server 配置里再多加一個參數(shù)就可以搞定了大渤。
```javascript
server {
? ? listen? ? ? 443 ssl http2;
? ? server_name? www.xxx.net;
? ? ssl_certificate? ? ? ? xxx.crt;
? ? ssl_certificate_key? ? xxx.key;
```
注意“l(fā)isten”指令,在“ssl”后面多了一個“http2”掸绞,這就表示在 443 端口上開啟了 SSL 加密泵三,然后再啟用 HTTP/2。
配置服務(wù)器推送特性可以使用指令“http2_push”和“http2_push_preload”
``` javascript
http2_push /style/xxx.css;
http2_push_preload on;
```javascript
不過如何合理地配置推送是個難題集漾,如果推送給瀏覽器不需要的資源,反而浪費了帶寬具篇。
這方面暫時沒有一般性的原則指導(dǎo)纬霞,你必須根據(jù)自己網(wǎng)站的實際情況去“猜測”客戶端最需要的數(shù)據(jù)驱显。
優(yōu)化方面,HTTPS 的一些策略依然適用埃疫,比如精簡密碼套件、ECC 證書栓霜、會話復(fù)用翠桦、HSTS 減少重定向跳轉(zhuǎn)等等销凑。
但還有一些優(yōu)化手段在 HTTP/2 里是不適用的,而且還會有反效果仅炊,比如說常見的精靈圖(Spriting)、資源內(nèi)聯(lián)(inlining)抚垄、域名分片(Sharding)等蜕窿,至于原因是什么,我把它留給你自己去思考(提示呆馁,與緩存有關(guān))桐经。
還要注意一點,HTTP/2 默認(rèn)啟用 header 壓縮(HPACK)浙滤,但并沒有默認(rèn)啟用 body 壓縮阴挣,所以不要忘了在 Nginx 配置文件里加上“gzip”指令,壓縮 HTML瓷叫、JS 等文本數(shù)據(jù)屯吊。
**?應(yīng)用層協(xié)議協(xié)商(ALPN) **
最后說一下 HTTP/2 的“服務(wù)發(fā)現(xiàn)”吧。
你有沒有想過摹菠,在 URI 里用的都是 HTTPS 協(xié)議名盒卸,沒有版本標(biāo)記,瀏覽器怎么知道服務(wù)器支持 HTTP/2 呢次氨?為什么上來就能用 HTTP/2蔽介,而不是用 HTTP/1 通信呢?
答案在 TLS 的擴展里煮寡,有一個叫“ALPN”(Application Layer Protocol Negotiation)的東西虹蓄,用來與服務(wù)器就 TLS 上跑的應(yīng)用協(xié)議進行“協(xié)商”。
客戶端在發(fā)起“Client Hello”握手的時候幸撕,后面會帶上一個“ALPN”擴展薇组,里面按照優(yōu)先順序列出客戶端支持的應(yīng)用協(xié)議。
就像下圖這樣坐儿,最優(yōu)先的是“h2”律胀,其次是“http/1.1”,以前還有“spdy”貌矿,以后還可能會有“h3”炭菌。
服務(wù)器看到 ALPN 擴展以后就可以從列表里選擇一種應(yīng)用協(xié)議,在“Server Hello”里也帶上“ALPN”擴展逛漫,告訴客戶端服務(wù)器決定使用的是哪一種黑低。因為我們在 Nginx 配置里使用了 HTTP/2 協(xié)議,所以在這里它選擇的就是“h2”酌毡。
這樣在 TLS 握手結(jié)束后克握,客戶端和服務(wù)器就通過“ALPN”完成了應(yīng)用層的協(xié)議協(xié)商,后面就可以使用 HTTP/2 通信了阔馋。
** 小結(jié) **
今天我們討論了是否應(yīng)該遷移到 HTTP/2玛荞,還有應(yīng)該如何遷移到 HTTP/2。
HTTP/2 完全兼容 HTTP/1呕寝,是“更安全的 HTTP勋眯、更快的 HTTPS”,頭部壓縮下梢、多路復(fù)用等技術(shù)可以充分利用帶寬客蹋,降低延遲,從而大幅度提高上網(wǎng)體驗孽江;
TCP 協(xié)議存在“隊頭阻塞”,所以 HTTP/2 在弱網(wǎng)或者移動網(wǎng)絡(luò)下的性能表現(xiàn)會不如 HTTP/1岗屏;
遷移到 HTTP/2 肯定會有性能提升漱办,但高流量網(wǎng)站效果會更顯著娩井;
如果已經(jīng)升級到了 HTTPS似袁,那么再升級到 HTTP/2 會很簡單;
TLS 協(xié)議提供“ALPN”擴展扬霜,讓客戶端和
服務(wù)器協(xié)商使用的應(yīng)用層協(xié)議而涉,“發(fā)現(xiàn)”HTTP/2 服務(wù)婴谱。