連線池
對於 HTTP 流量,Envoy 支援抽象連線池,這些連線池分層在底層網路協定(HTTP/1.1、HTTP/2、HTTP/3)之上。利用篩選器程式碼不需要知道底層協定是否支援真正的多工處理。實際上,底層實作具有以下高階屬性
HTTP/1.1
HTTP/1.1 連線池會根據需要取得與上游主機的連線(直到斷路限制)。當連線可用時,請求會被繫結到連線,可能是因為連線已完成處理先前的請求,或是因為新連線已準備好接收其第一個請求。HTTP/1.1 連線池不使用管線化,因此如果上游連線中斷,則只需要重置單一下游請求。
HTTP/2
HTTP/2 連線池在單一連線上多工處理多個請求,直到 最大並行串流 和 每個連線的最大請求數 所施加的限制。HTTP/2 連線池會建立滿足請求所需的盡可能多的連線。如果沒有限制,則只會是一個連線。如果收到 GOAWAY 框架,或連線達到 每個連線的最大請求數 限制,連線池將會排空受影響的連線。一旦連線達到其 最大並行串流限制,它將被標記為忙碌,直到有可用的串流。每當有待處理的請求且沒有可以分派到的連線時,就會建立新連線(直到連線的斷路器限制)。當 Envoy 作為反向 Proxy 時,HTTP/2 是首選的通訊協定,因為連線很少(如果有的話)會中斷。
HTTP/3
HTTP/3 連線池在單一連線上多工處理多個請求,直到 最大並行串流 和 每個連線的最大請求數 所施加的限制。HTTP/3 連線池會建立滿足請求所需的盡可能多的連線。如果沒有限制,則只會是一個連線。如果收到 GOAWAY 框架,或連線達到 每個連線的最大請求數 限制,連線池將會排空受影響的連線。一旦連線達到其 最大並行串流限制,它將被標記為忙碌,直到有可用的串流。每當有待處理的請求且沒有可以分派到的連線時,就會建立新連線(直到連線的斷路器限制)。
自動協定選擇
對於作為轉送 Proxy 的 Envoy,首選設定是 AutoHttpConfig,透過 http_protocol_options 進行設定。依預設,它會使用 TCP 和 ALPN 來選取可用的最佳 HTTP/2 和 HTTP/1.1 協定。
對於具有 HTTP/3 的自動 HTTP,必須透過 alternate_protocols_cache_options 設定替代協定快取。只有透過 HTTP 替代服務(最終是 HTTPS DNS 資源記錄或將手動設定的「QUIC 提示」)宣告支援 HTTP/3 的伺服器才會嘗試 HTTP/3 連線。如果不存在此類宣告,則會改用 HTTP/2 或 HTTP/1。
嘗試 HTTP/3 時,Envoy 目前會先嘗試 QUIC 連線,然後在 300 毫秒後,如果沒有建立 QUIC 連線,也會嘗試建立 TCP 連線。將會使用任何成功握手的連線來進行初始串流,但如果同時建立 TCP 和 QUIC 連線,最終會優先使用 QUIC。
此外,由於 HTTP/3 在 QUIC(使用 UDP)上執行,而不是在 TCP(HTTP/1 和 HTTP/2 使用)上執行。網路裝置通常會封鎖 UDP 流量,因此封鎖 HTTP/3。這表示網路可能會封鎖上游 HTTP/3 連線嘗試,並會回復為使用 HTTP/2 或 HTTP/1。在有顯著的生產執行時間之前,此程式碼路徑仍被視為 alpha 版,但被認為可以使用。
Happy Eyeballs 支援
Envoy 支援 Happy Eyeballs,RFC8305,用於上游 TCP 連線。對於使用 LOGICAL_DNS 的叢集,此行為是透過在 config.cluster.v3.Cluster.DnsLookupFamily 中將 DNS IP 位址解析原則設定為 ALL 選項來傳回 IPv4 和 IPv6 位址來設定。對於使用 EDS 的叢集,此行為是透過使用 additional_addresses 欄位為主機指定額外的 IP 位址來設定。在此欄位中指定的位址會附加到 address 中指定的一個位址的清單中
所有位址的清單將會根據 Happy Eyeballs 規格進行排序,並會嘗試連線到清單中的第一個位址。如果此連線成功,將會使用它。如果失敗,則會嘗試連線到清單中的下一個位址。如果在 300 毫秒後連線仍在連線中,則會嘗試連線到清單中的下一個位址。
最終將會成功嘗試連線到其中一個位址,在這種情況下將會使用該連線,否則所有嘗試都會失敗,在這種情況下將會報告連線錯誤。
HTTP/3 的 Happy-Eyeballs 類似支援有限。當使用 ref:auto_config <envoy_v3_api_field_extensions.upstreams.http.v3.HttpProtocolOptions.auto_config> 來進行具有 TCP 容錯移轉的 HTTP/3 時,Envoy 將會盡最大努力嘗試兩個位址系列。與 TCP Happy Eyeballs 支援一樣,Envoy 允許第一個 HTTP/3 嘗試連線的時間為 300 毫秒。如果連線明確失敗或 300 毫秒逾時到期,如果 DNS 解析導致前兩個解析的位址屬於不同的位址系列,則會建立使用第二個位址的第二個 HTTP/3 連線池,Envoy 將會嘗試使用替代位址系列建立 HTTP/3 連線。在這種情況下,只有在建立 TCP 連線且兩個 HTTP/3 連線都失敗時,才會將 HTTP/3 標記為中斷。
連線池的數量
每個叢集中的每個主機都會有一個或多個連線池。如果叢集設定了單一明確的協定,則主機可能只有單一連線池。但是,如果叢集支援多個上游協定,除非它使用 ALPN,否則可能會為每個協定分配一個連線池。也會為下列每個功能分配單獨的連線池
可雜湊且標記為與上游連線共用的下游 篩選器狀態物件。
每個工作執行緒都會維護其自己的叢集連線池,因此如果 Envoy 有兩個執行緒,且叢集同時支援 HTTP/1 和 HTTP/2,則將至少有 4 個連線池。
健康檢查互動
如果 Envoy 設定為主動或被動健康檢查,當主機從可用狀態轉換為不可用狀態時,所有連線池的連線都將會被關閉。如果主機重新進入負載平衡輪換,它將會建立新的連線,這將最大化解決不良流量(由於 ECMP 路由或其他原因)的可能性。