NGINX QUIC 和 HTTP/3 開發路線圖

語言: CN / TW / HK

原文作者:Liam Crilly of F5 
原文連結:​​NGINX QUIC 和 HTTP/3 開發路線圖 - NGINX​​ 
轉載來源:NGINX 官方網站


Internet 從未停止過前進的腳步。早在 2015 年 HTTP/2 標準化之前,QUIC 的相關工作就已經開始了,而在之後 QUIC 成為了 HTTP/3。在向 IETF 提交首個 QUIC 規範草案五年之後的現在,我們有了 RFC 9000“QUIC:基於 UDP 的多路複用安全傳輸”。

當然,演變之路並不是那麼輕鬆。在撰寫本文時,業內共釋出了四個 RFC,用於描述核心 QUIC 傳輸層和加密層。而另外 11 個相關的規範(包括 ​​HTTP/3​​ 的最終定義)仍處於草案階段。然而,許多客戶端和服務端的HTTP/3實現已得到廣泛使用。事實上,得益於 CDN 提供商和科技巨頭們向來緊跟標準草案的步伐,20% 的網站現已支援 HTTP/3。我們也不例外。

如欲深入瞭解 HTTP 的發展歷程以及我們對 HTTP/3 和 QUIC 的實現,請觀看此視訊:

去年,我們推出了​​QUIC 和 HTTP/3 的技術預覽版​​,之後還開展了許多工作。以下是 NGINX 實現 QUIC 和 HTTP/3 的關鍵開發工作摘要:

  • 我們​實現了多個 HTTP/3 草案版本​​,從​​草案 23​​​ 到​​草案 29​​​(目前應用最廣泛的版本),當然還有已經發布的 HTTP/3 標準(​​草案 34​​)。
  • 我們不斷將 ​​NGINX 主線分支中的所有變更​合併​到​ nginx-quic 分支​​,以便所有新功能(和問題修復)都可以在QUIC開發分支中進行測試。
  • 我們​參與了 QUIC 互操作測試​,以便持續測試我們的實現與多種客戶端的互操作性,並與其他伺服器實現進行了對比。
  • 我們​開發了一個 eBPF 程式​​以利用 NGINX 的多程序架構。NGINX 使用多工作程序模式,可充分利用CPU多核來擴充套件效能。為了獲得最大效率,針對每一個連線,我們傾向於使用同一工作程序來進行處理。然而 QUIC 使得這種處理方式變得棘手,因為連線不再與客戶端的 IP 地址繫結,且 Linux 核心不提供 UDP 埠到程序的關聯。為了解決這個問題,我們實現了一個 eBPF 擴充套件來整合 ​​SO_REUSEPORT​​,因此可以將 QUIC 連線 ID 對映到首先處理它的工作程序。這被巧妙地整合到 NGINX 核心中,以便 NGINX 將 eBPF 位元組碼載入到核心的套接字選擇程式碼中。
  • 我們​整合了 NGINX 的連線處理程式碼​​,以簡化長連線的配置方式。以前僅適用於 HTTP/1.1 的配置指令現在也同樣適用於 HTTP/2,未來還將適用於 QUIC + HTTP/3。您不會再因協議版本不同而需要使用不同的指令來處理相同的功能了。請參閱 ​​client_header_timeout​​​、​​keepalive_requests​​​、​​keepalive_timeout​​​ 及 ​​large_client_header_buffers​​ 指令。
  • 我們將​新增的程式碼重構​為兩部分:較小的部分包含影響 NGINX 核心的更改,較大的部分包含傳輸協議的實現。通過以這種方式組織程式碼庫,我們可以將對 NGINX 核心的變更保持在最低限度,從而降低將引入安全漏洞到NGINX的風險。

NGINX 路線圖

我們的 QUIC + HTTP/3 路線圖有兩大里程碑:

  1. 將 ​nginx-quic​ 開發分支合併到 NGINX 主線分支
  2. 實現效能優化

QUIC 和 HTTP/3 協議的實現已基本完成,我們正在謹慎地將 nginx-quic​​ 分支中的新程式碼合併到 ​​NGINX 主線分支​​​(即我們釋出新功能的主線版本)。對 NGINX 核心的更改相對較小(約 3,000 行程式碼),合併正在順利進行中。而工作量比較大的是合併傳輸協議程式碼(約 27,000 行程式碼)。根據以往​​將 HTTP/2 實現合併到 NGINX​​ 的經驗,這項工作預計將會耗時幾個月。

我們當前的目標是,在 2021 年底將程式碼全部合併到 NGINX 主線分支,之後它將被後續版本的 NGINX 主線分支及 NGINX Plus 所包含。

在這之後,我們將專注於優化效能。QUIC 的有些優勢是立竿見影的,但有些優勢則需要時日才能顯現。TCP 和 UDP 在作業系統核心和網路驅動程式層面的開發有著數十年的時間,因而具有一定優勢,但 QUIC 主要是在作業系統​​使用者空間​​​中實現的 —— 這意味著一些我們認為理所當然的事情(例如擁塞通知和​​首選資料包大小檢測​​),現在必須由每個客戶端和伺服器軟體供應商自行實現。


整合 QUIC 的 TLS 層

QUIC 中加密傳輸成為了網路協議棧中強制性、不可協商的組成部分。QUIC 支援 TLS 1.3 標準,但 TLS 的軟體實現也必須支援 QUIC 介面。NGINX 通常將 ​​OpenSSL​​​ 用作外部依賴項,這意味著我們可以使用 ​​官方 NGINX 開源版軟體包​​和 NGINX Plus 中的作業系統自帶的 SSL/TLS 庫。通過將加密實現從 NGINX 中解耦,我們可以在不升級 NGINX 的情況下修復 SSL/TLS 庫中的錯誤和安全漏洞。

在撰寫本文時,​​OpenSSL 尚不支援 QUIC​​​,而自帶支援 QUIC 的 SSL/TLS 庫的作業系統版本可能還需要好幾個月的時間才能被交付。我們的 QUIC 實現目前支援 ​​BoringSSL​​​ 和 ​​OpenSSL​​ 的 ​quictls 分支,不過它們必須使用 NGINX 進行編譯。

我們預計,在我們將 nginx-quic 開發分支合併到 NGINX 主線分支的過程中, SSL/TLS 庫對於 QUIC 的支援情況也將變得更加清晰。


如何助我們一臂之力

您可以幫助我們測試我們的 QUIC + HTTP/3 實現。您發現的錯誤和邊界情況越多,我們就能越快地完成合並過程,從而使 NGINX 正式支援 QUIC + HTTP/3。

  • 如果您熟悉 QUIC 和/或 HTTP/3,請對您熟悉的部分進行程式碼評審。
  • 如果您執行大規模Internet服務,請為一些使用者或服務部署 ​nginx-quic​,以進行 A/B 測試。
  • 如果您管理 Web 網站和/或應用,請在您的自動化測試(而非當前版本)中試用 ​nginx-quic​。
  • 煩請您通過 ​​NGINX 開發者郵件列表​​與我們分享您的發現。

如要試用 nginx-quic 實現,您只需用瀏覽器開啟​​ https://quic.nginx.org/​​​ ,​即可檢視 ​​README​​ 瞭解更多資訊。如要在您自己的環境中進行快速概念驗證,請使用該 ​Dockerfile 構建自己的 nginx-quic 映象,然後按照前面提到的 README 中的配置說明進行配置。

[編者按 – 後面的 Dockerfile 已在 2021 年 12 月更新,以修改原始版本中的錯誤。]

FROM nginx:1.21.1 AS build


WORKDIR /src
RUN apt-get update && \
    apt-get install -y git gcc make g++ cmake perl libunwind-dev golang && \
    git clone https://boringssl.googlesource.com/boringssl && \
    mkdir boringssl/build && \
    cd boringssl/build && \
    cmake .. && \
    make


RUN apt-get install -y mercurial libperl-dev libpcre3-dev zlib1g-dev libxslt1-dev libgd-ocaml-dev libgeoip-dev && \
    hg clone https://hg.nginx.org/nginx-quic   && \
    hg clone http://hg.nginx.org/njs -r "0.6.2" && \
    cd nginx-quic && \
    hg update quic && \
    auto/configure `nginx -V 2>&1 | sed "s/ \-\-/ \\\ \n\t--/g" | grep "\-\-" | grep -ve opt= -e param= -e build=` \
                   --build=nginx-quic --with-debug  \
                   --with-http_v3_module --with-http_quic_module --with-stream_quic_module \
                   --with-cc-opt="-I/src/boringssl/include" --with-ld-opt="-L/src/boringssl/build/ssl -L/src/boringssl/build/crypto" && \
    make


FROM nginx:1.21.1
COPY nginx.conf /etc/nginx/nginx.conf
COPY www.example.com.crt /etc/ssl/www.example.com.crt
COPY www.example.com.key /etc/ssl/www.example.com.key
COPY index.html /etc/nginx/html/index.html
COPY --from=build /src/nginx-quic/objs/nginx /usr/sbin
RUN /usr/sbin/nginx -V > /dev/stderr
EXPOSE 8443

更多資源

想要更及時全面地獲取NGINX相關的技術乾貨、互動問答、系列課程、活動資源?

請前往NGINX開源社群: