QUIC代理服務的實現

QUIC Proxy

隨着http/3的臨近,quic越來越受到關注,關於quic的介紹網上有很多,這裏就不做介紹了。目前,quic有兩個版本Google QUIC 和 IETF QUIC,隨着IETF的最終定稿,谷歌也會向其靠攏。
作爲全球最大的瀏覽器Chrome很早以前就開始支持GQUIC(Google QUIC),並且Youtube已經開始全站應用GQUIC協議,所以本文介紹的QUIC代理服務實現的是谷歌版本的quic服務。

QUIC Proxy 特點

基於chromium開源項目(Chrome開源項目)

chromium 本身提供了一個測試用的quic服務,但是這個服務是單進程,且http回源需要整個文件下載完才能發給前端,大的視頻文件這種方式是不能接受的,所以在epoll_quic_server這個demo基礎上,基於chromium架構,重新開發了一個支持高併發,可商用的quic to http代理服務。
相較於其他quic開源項目, 因爲使用chromium中的quic協議,所以可以做到與chrome瀏覽器做到同步更新,完美的兼容各個版本的chrome內核瀏覽器,避免了其他開源項目quic協議更新慢,實現不完全的苦惱。

使用最新的linux內核特性解決性能問題

quic服務屬於udp服務,udp的服務在性能上有兩個很難解決的問題:

  1. 多核的利用問題,由於不像tcp那樣,accept上來一個連接後,可以分配到一個固定的線程或進程上進行讀寫,udp服務recvfrom的數據包無法確定哪個線程會收到,所以需要通過消息隊列,或加鎖的方式,進行串行處理。
  2. 頻繁的系統調用導致cpu過高問題,相對於tcp服務,udp服務往往cpu都比較高,是由於爲了避免網絡傳輸過程中IP包被拆包,一般包的大小都會小於路由器的MTU,假如是1k一個包,那麼發送64k的數據,需要調用64次sendto系統調用,大量的用戶態與內核態的切換導致了cpu過高。

高版本的linux內核提供了新的系統調用或參數來解決這些問題。使用SO_REUSEADDR可以讓每個線程或進程打開相同端口的套接字,有各自獨立的接收發送窗口,內核根據四元組(srcip,srcport,dstip,ditport)做hash,映射到不同的進程上,保證相同的用戶ip和端口每次都被相同的進程recvfrom到。使用sendmmsg系統調用,類似於一次系統調用發送一個二維數組,減少系統調用的次數,recvmmsg同理。
QUIC Proxy 使用了這些新技術,提高服務的性能。

實操

實際如何商用呢?其實很簡單,只是在原有業務前面,加上一層quic代理服務,以chrome瀏覽器舉例。

  1. chrome第一次請求會用TCP http請求原有業務。
  2. 原有業務在返回的http respond header加入 alt-svc: quic=":443"; ma=2592000; v=“46,44,43,39”。
  3. 後續業務請求, chrome會使用quic協議請求資源。

歡迎使用

目前quic代理服務已經提交到了github上 quic_proxy,歡迎下載使用,提出改進方法和bug。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章