QUIC是Quick UDP Internet Connections的縮寫,谷歌出品的傳輸協議,使用UDP替換TCP來支持HTTP通訊。UDP自己不是可靠傳輸, 經過在其上添加流控、校驗等功能,QUIC能夠實現可靠傳輸,並且相比於TCP,它的流控功能在用戶空間而不在內核空間,那麼使用者就 不受限於CUBIC或是BBR,而是能夠自由選擇,甚至根據應用場景自由調整優化。html
QUIC爲現有 tcp + https + http2
組合存在的諸多問題提供瞭解決方案:nginx
最新版的Chrome瀏覽器默認啓用QUIC協議,只要後端服務器支持,Chrome就會使用QUIC協議。如今谷歌自家的大部分網站都使用了QUIC協議。git
不改變現有Web服務架構,咱們能夠經過在內網添加一層反向代理,快速啓用QUIC協議。這樣,對於支持QUIC的客戶端,使用QUIC協議改善外網通訊, 對於不支持QUIC的客戶端,依舊沿用TCP通訊,並且就算這個反向代理掛掉了,Chrome瀏覽器還能夠切回TCP通訊,沒有增長服務中斷風險。github
既然谷歌自家的網站已經啓用了QUIC,咱們能夠訪問試試看。怎麼知道打開的網站是否走了QUIC協議呢,咱們能夠經過wireshark抓包驗證,但還有 更方便的方法,直接用Chrome提供的工具,主要有三種方法:chrome
開發者工具Security選項卡後端
用Chrome瀏覽器打開谷歌官網www.google.com.hk ,按F12打開 開發者工具,切換到Security選項卡,刷新網頁後選擇左側一個源站,能夠看到 它使用的協議:瀏覽器
Chrome插件: HTTP/2 and SPDY indicator
緩存
從Chrome應用商店搜索插件名字能夠下載,它用不一樣顏色標識當前網站使用的是HTTP(灰色),HTTP2(藍色)或者QUIC(綠色)服務器
網絡調試頁 chrome://net-internals
網絡
Chrome還提供一個url用於調試網絡狀態,在瀏覽器中訪問 chrome://net-internals/
地址,或者點擊上述插件的小圖標便可進入。 這裏提供了很是豐富的監控和調試功能,咱們重點須要關注QUIC頁面和Alt-Svc頁面。
點擊左欄的QUIC能夠查看瀏覽器QUIC的版本配置以及QUIC會話。
點擊左欄的Alt-Svc能夠查看站點QUIC的端口、超時等狀況。本頁面的一個示例以下表:
| --------------Server -------------------| Alternative Service -------------| | ------------------------------------------ | ---------------------------------------- | | `https://client4.google.com` | quic :443, expires 2018-04-18 16:54:41 | | `https://zabbix.test.com` | quic :443, expires 2018-03-20 16:53:30 (broken) |
能夠看到client4.google.com這個域名啓用了QUIC協議,在UDP 443端口,後面是緩存超時。特別須要注意的是,zabbix.test.com這個地址, 它的最後有個(broken),意思是說雖然這個網站宣稱本身支持QUIC協議,即有響應頭 Alt-Svc: quic:443
,可是瀏覽器發出的QUIC請求 未獲得響應。這種狀況有多是防火牆屏蔽了UDP 443端口,也多是後端的QUIC服務掛了。
Chrome瀏覽器初次發出QUIC請求會使用的賽跑的方式,同時發出TCP和QUIC的請求,那個先返回就用哪一個,確認QUIC服務可用以後,後續請求 直接使用QUIC協議。可是,若是發現QUIC通道不可用了,它就把它標記爲(broken),切回TCP鏈接。
QUIC是谷歌的,chromium中的QUIC實現算是官方實現,保證QUIC版本最新,但整個項目代碼量太大,網絡模塊依賴較多, 又使用了本身的一套編譯工具,若是本身從中剝離QUIC協議棧也比較麻煩。
chromium提供的C++接口很底層,須要本身實現會話、鏈接和流的管理,反向代理接收QUIC請求以後,須要構造UrlRequest發日後端。 要實現這些功能,還要先了解chromium的線程、消息循環、智能指針等一系列基礎構件的使用方法,比較複雜,好在網上能找到一個樣例。 這是一個尚在審覈的提交 ,未來有望合入chromium主分支,能讓用戶快速啓用QUIC嚐鮮試用。
從chromium剝離的一個QUIC協議部分,可是其github主頁已宣佈再也不支持,僅做實驗使用。
goquic封裝了libquic的go語言封裝,而libquic也是從chromium剝離的,好幾年不維護了,僅支持到QUIC 36, goquic提供一個反向代理,測試發現因爲QUIC版本過低,最新chrome瀏覽器已沒法支持。
quic-go是徹底用go寫的QUIC協議棧,開發很活躍,已在 Caddy 中使用,MIT許可,目前看是比較好的方案。它的接口和goquic接口 很相似,能夠參考goquic反向代理的 代碼 ,把QUIC部分替換爲quic-go便可。最簡單的實現方法,初始化一個反向代理handler 直接調用h2quic.ListenAndServeQUIC,主要代碼以下:
import ( "net/http/httputil" "github.com/lucas-clemente/quic-go/h2quic" ) proxyHandler := httputil.NewSingleHostReverseProxy("localhost:80") err = h2quic.ListenAndServeQUIC(addrStr, cert, key, proxyHandler)
要編譯這個反向代理,須要把整個chromium項目下載下來,能夠按照 教程 操做,而後checkout這個 包含代理的提交 ,用ninja編譯, 編譯時只選擇 quic_server
和 quic_client
便可。這個反向代理的實現,在 quic_server
的基礎上加了一個啓動選項 --mode=proxy
來開啓反向代理模式,好比原來的服務在本機的80端口,使用原來的證書和私鑰啓動反向代理:
./quic_server --mode=proxy --quic_proxy_backend_url=http://localhost --certificate_file=leaf_cert.pem --key_file=leaf_cert.pkcs8
啓動以後可使用QUIC測試客戶端鏈接試試看:
./quic_client --host=127.0.0.1 --port=6121 https://www.example.org/index.html --disable-certificate-verification
第一次http請求仍是會從TCP端口先到達原始服務器,經過在響應中添加Alt-Svc頭告訴客戶端可以支持QUIC, 以nginx爲例,在配置文件的http塊中添加:
add_header Alt-Svc 'quic=":443"'
這時候用Chrome瀏覽器去訪問你的網站,就可使用QUIC協議了。
根據上面介紹的方法,去Chrome瀏覽器中驗證一下,若是指示器不是綠色的,能夠點開看看是否(broken)了,嘗試抓包查找網絡緣由,調整防火牆策略。
移動互聯網時代,光依靠Chrome瀏覽器可不行啊,谷歌提供了 cronet ,它是chromium網絡協議棧的封裝,能夠用於Android和iOS平臺,很方便 集成到手機APP中。 這裏 能夠下載編譯好的cronet庫。
2018-03-19 週一