连接池
对于 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 充当反向代理时,HTTP/2 是首选的通信协议,因为连接很少(如果有的话)会断开。
HTTP/3
HTTP/3 连接池在单个连接上复用多个请求,最多达到 最大并发流 和 每个连接的最大请求数 限制。HTTP/3 连接池会建立尽可能多的连接来服务请求。如果没有限制,这将只有一个连接。如果收到 GOAWAY 帧或连接达到 每个连接的最大请求数 限制,连接池将排空受影响的连接。一旦连接达到 最大并发流限制,它将被标记为繁忙,直到有流可用。只要有未连接的待处理请求,就会建立新的连接(最多达到连接的断路器限制)。
自动协议选择
对于充当转发代理的 Envoy,首选配置是 AutoHttpConfig,通过 http_protocol_options 配置。默认情况下,它将使用 TCP 和 ALPN 来选择最佳的可用协议 HTTP/2 和 HTTP/1.1。
对于具有 HTTP/3 的自动 HTTP,必须通过 alternate_protocols_cache_options 配置备用协议缓存。HTTP/3 连接仅尝试连接到通过 HTTP 替代服务(最终是 HTTPS DNS 资源记录 或将手动配置的“QUIC 提示”)广告 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 路由或其他因素)的可能性。