CDN更快一步,藍(lán)汛QUIC協(xié)議的應(yīng)用與測(cè)試
CDN 行業(yè)的技術(shù)出發(fā)點(diǎn)就是把用戶(hù)訪問(wèn)網(wǎng)站業(yè)務(wù)的時(shí)間縮短,再縮短。因此,CDN服務(wù)商都盡可能把服務(wù)節(jié)點(diǎn)部署到離最終網(wǎng)民接近的網(wǎng)絡(luò)節(jié)點(diǎn)上。除了從系統(tǒng)部署方式上提高網(wǎng)民訪問(wèn)的速度,減少網(wǎng)絡(luò)傳輸?shù)臅r(shí)間之外,在網(wǎng)民用于訪問(wèn)網(wǎng)站的網(wǎng)絡(luò)協(xié)議上也在不斷地演進(jìn)變化。本文將根據(jù)藍(lán)汛對(duì)QUIC協(xié)議的應(yīng)用和測(cè)試經(jīng)驗(yàn),在該協(xié)議的開(kāi)發(fā)、配置和啟動(dòng)等技術(shù)環(huán)節(jié)進(jìn)行分享。
由SPDY到HTTP/2
2009年,Google在 “Make the Web faster” 的目標(biāo)下,針對(duì)HTTP協(xié)議提出了SPDY。當(dāng)時(shí),提出SPDY的目標(biāo)是在HTTP基礎(chǔ)上,將頁(yè)面加載的速度提高50%,同時(shí)也將部署未來(lái)新的應(yīng)用協(xié)議的復(fù)雜性降低。
SPDY被證明是成功的,因?yàn)樗谝韵?個(gè)方面提升了整體的性能:
多路復(fù)用:通過(guò)同一個(gè)域名使用1個(gè)或者相對(duì)于HTTP/1.1更少的TCP連接數(shù),SPDY避免了頭部阻塞(HOL),同時(shí)由于減少了TCP連接,也就降低了新開(kāi)TCP連接的系統(tǒng)開(kāi)銷(xiāo)。
頭部壓縮:通過(guò)對(duì)HTTP Header中反復(fù)發(fā)送的字段進(jìn)行壓縮,通過(guò)SPDY之后,請(qǐng)求頭和響應(yīng)頭的體積都大大減小。
請(qǐng)求的優(yōu)先級(jí)區(qū)分:高優(yōu)先級(jí)的資源被優(yōu)先請(qǐng)求,因此,對(duì)于頁(yè)面解析的關(guān)鍵元素也就被優(yōu)先下載展示。
Server Push / Server Hint: Server Push 在用戶(hù)端還沒(méi)有請(qǐng)求的前提下,由服務(wù)端推送相關(guān)內(nèi)容給用戶(hù)端;Server Hint是在服務(wù)端將一些資源標(biāo)記了優(yōu)先級(jí),用戶(hù)端在請(qǐng)求的時(shí)候可以根據(jù)目前的帶寬情況(限制情況)決定是否下載。
因?yàn)镾PDY在針對(duì)HTTP/1.x上性能的提升,IETF HTTP 工作組基于SPDY通過(guò)HTTP/2來(lái)優(yōu)化HTTP協(xié)議。
HTTP/2 借鑒了SPDY的優(yōu)化策略和思路,然而,兩者之間也有不同點(diǎn):
HTTP/2和SPDY的主要區(qū)別在于頭部壓縮的算法: HTTP/2使用的是HPACK壓縮的方式,而SPDY使用的是DEFLATE方式壓縮。
盡管如此,HTTP/2和SPDY還都是基于TCP作為連接層的基礎(chǔ),因此,性能的提升都是在同一個(gè)基礎(chǔ)之上的。TCP協(xié)議飽受詬病的那些擁塞和丟包處理的方式影響著它們的性能發(fā)揮。
由TCP到UDP,QUIC的提出
QUIC 是(Quick Udp Internet Connection)的首字母縮寫(xiě)。是由 Google 提出的使用 UDP 進(jìn)行多路并發(fā)傳輸?shù)膮f(xié)議。
QUIC相比上文中 TCP+TLS+HTTP/2 組合有如下優(yōu)勢(shì) :
減少了 TCP 三次握手及 TLS 握手時(shí)間。
改進(jìn)的擁塞控制。
避免隊(duì)頭阻塞的多路復(fù)用。
連接遷移。
前向冗余糾錯(cuò)。
根據(jù)Jana Iyengar在2016年IETF柏林會(huì)議上針對(duì)QUIC的架構(gòu)(如下圖)采用QUIC采用UDP替代TCP實(shí)現(xiàn)的傳輸方式相對(duì)于TCP+TLS+HTTP/2的架構(gòu)有了很大的變化。
目前看,早期在Google應(yīng)用QUIC協(xié)議的業(yè)務(wù)效果相當(dāng)不錯(cuò),93%的業(yè)務(wù)沒(méi)有因?yàn)镼UIC應(yīng)用不成功而回滾到原先架構(gòu);應(yīng)用QUIC協(xié)議的業(yè)務(wù)降低 了5%的頁(yè)面加載時(shí)間,而Youtube應(yīng)用QUIC后,播放中再緩存降低了30%。
QUIC開(kāi)發(fā)和測(cè)試
QUIC測(cè)試開(kāi)發(fā)環(huán)境搭建:目前國(guó)內(nèi)有的廠商已經(jīng)在部分應(yīng)用平臺(tái)使用了QUIC協(xié)議,然而,支持QUIC的公有云目前還都沒(méi)有。因此,我們?nèi)绻枰獪y(cè)試QUIC的應(yīng)用和平臺(tái),還需要自己進(jìn)行搭建。下面,就將我們?cè)趦?nèi)部進(jìn)行QUIC初期測(cè)試時(shí)候的經(jīng)驗(yàn)分享給大家。
Chrome瀏覽器打開(kāi)QUIC:搭建一個(gè)最簡(jiǎn)單的實(shí)驗(yàn)環(huán)境,我們需要一個(gè)支持QUIC的server端和支持QUIC的客戶(hù)端。
支持QUIC的客戶(hù)端,最簡(jiǎn)單直接的方式就是采用Chrome瀏覽器。通常而言,Chrome瀏覽器還沒(méi)有打開(kāi)QUIC協(xié)議的支持,因此,需要通過(guò)以下步驟來(lái)操作:
在Chrome地址欄輸入chrome://flags訪問(wèn)實(shí)驗(yàn)性的功能開(kāi)關(guān)
在頁(yè)面中搜索QUIC關(guān)鍵字
將QUIC的開(kāi)關(guān)由“Default”變?yōu)?ldquo;Enable”
重啟Chrome
QUIC協(xié)議打開(kāi)后,要檢視相關(guān)的連接和配置需要通過(guò)在Chrome瀏覽器地址欄輸入chrome://net-internals/#quic 來(lái)打開(kāi)相關(guān)的頁(yè)面。
由這個(gè)截圖,我們可以看到,目前chrome(69)的QUIC版本是v43,這是個(gè)相當(dāng)新的版本,當(dāng)然也會(huì)對(duì)QUIC的server端選擇造成困擾。
Caddy Server支持QUIC:Caddy 和我們常用的Apache、Nginx一樣,是一個(gè)Web Server,而且是使用go語(yǔ)言開(kāi)發(fā)的。相對(duì)于后兩者,它具備以下一些優(yōu)點(diǎn):
內(nèi)建對(duì)HTTP/2的支持
對(duì)Let'sencrypt的支持
對(duì)QUIC支持
對(duì)多核系統(tǒng)的支持
易于部署
對(duì)IPv6的支持
其中第2、第3點(diǎn)是滿足我們后面的實(shí)驗(yàn)的重要功能需求。
安裝Caddy server
我們采用的是Centos7系統(tǒng),安裝Caddy使用直接從getcaddy.com直接拉取編譯好的版本:
$ curl -s https://getcaddy.com | bash
腳本執(zhí)行的過(guò)程中,需要提供sudo權(quán)限讓caddy程序安裝到/usr/local/bin目錄下。
等腳本執(zhí)行完我們需要為caddy創(chuàng)建一個(gè)沒(méi)有登錄權(quán)限的用戶(hù),如“caddy”:
$ sudo adduser -r -d /var/www -s /sbin/nologin caddy
然后我們要建立www的目錄,配置文件caddyfile的目錄,及其他一些相關(guān)權(quán)限:
$ sudo mkdir /etc/caddy
$ sudo chown -R root:caddy /etc/caddy
$ sudo touch /etc/caddy/Caddyfile
$ sudo mkdir /etc/ssl/caddy
$ sudo chown -R caddy:root /etc/ssl/caddy
$ sudo chmod 0770 /etc/ssl/caddy
$ sudo mkdir /var/www
$ sudo chown caddy:caddy /var/www
配置caddy的系統(tǒng)服務(wù)
由于我們使用的是Centos 7,使用的是systemd管理系統(tǒng)服務(wù)。方便的是,caddy的systemd服務(wù)腳本可以從以下地址下載:
$sudo curl -s
https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service-o /etc/systemd/system/caddy.service
我們需要修改一下caddy的service文件:
/etc/systemd/system/caddy.service當(dāng)中User和Group信息,將它們改為caddy:
; User and group the process will run as.
User=caddy
Group=caddy
reload一下,以使修改生效:
$ sudo systemctl daemon-reload
現(xiàn)在,在啟動(dòng)caddy之前,我們還需要配置一下Let'sencrypt的自動(dòng)TLS。
配置Let's encrypt自動(dòng)TLS
要通過(guò)Caddy使用Let'sencrypt的自動(dòng)TLS,要滿足以下條件:
Caddy需要綁定443端口,同時(shí),這個(gè)端口要從外網(wǎng)可訪問(wèn)
Caddy HTTP只能設(shè)定為80端口,同時(shí),TLS不能從caddy的配置里關(guān)掉
Caddy里面的server設(shè)置的域名必須是真實(shí)可解析的域名,不能使localhost,證書(shū)將綁定這個(gè)域名
Caddy必須設(shè)定用于私鑰恢復(fù)的郵件地址
我們來(lái)配置/etc/caddy/Caddyfile來(lái)滿足要求:
假設(shè)我們的域名是quictesting.net,那么我們的配置文件可以是這樣:
quictesting.net {
root /var/www
gzip
tls admin@quictesting.net
}
別忘了在/var/www下面放上一個(gè)index.html文件,比如Hello World 。
$ sudo systemctl restart caddy
啟動(dòng)Caddy,然后我們?cè)偈褂肅hrome來(lái)訪問(wèn),可以觀察header信息:
說(shuō)明Let'sencrypt的HTTPS已經(jīng)起作用了。然而,這個(gè)時(shí)候,QUIC還沒(méi)有啟動(dòng)呢。
啟動(dòng)Caddy QUIC
通過(guò)修改systemd的服務(wù)啟動(dòng)選項(xiàng)來(lái)啟動(dòng)QUIC服務(wù)。
別忘了reload daemon以保證配置生效。這時(shí)候,我們?cè)儆胏hrome來(lái)訪問(wèn),看看header的變化。發(fā)現(xiàn)在響應(yīng)頭多了一行:
表明Caddy現(xiàn)在系統(tǒng)的QUIC版本是39。因此,這個(gè)時(shí)候,我們用Chrome去看QUIC信息,發(fā)現(xiàn)沒(méi)有active connection,原因就在于此。
解決方案:關(guān)于升級(jí)Caddy 使用的libquic,我們將在下期CC-Tech與您分享。