Envoy HTTP connection management基础

HTTP连接管理

  • Envoy通过内置的L4过滤器HTTP连接管理器将原始字节转换为HTTP应用层协议级别的消息和事件,例如接收到的标头和主体等,以及处理所有HTTP连接和请求共有的功能,包括访问日志、生成和跟踪请求ID,请求/响应头处理、路由表管理和统计信息等;

HTTP 协议

  • Envoy 的 HTTP 连接管理器原生支持 HTTP/1.1、WebSockets、HTTP/2 和 HTTP/3。它不支持 SPDY。Envoy 的 HTTP 支持首先被设计为 HTTP/2 多路复用代理。在内部,HTTP/2 术语用于描述系统组件。例如,HTTP 请求和响应发生在上。编解码器 API 用于将不同的有线协议转换为流、请求、响应等的协议不可知形式。在 HTTP/1.1 的情况下,编解码器将协议的串行/流水线功能转换为类似于 HTTP 的东西/2 到更高层。这意味着大部分代码不需要了解流是源自 HTTP/1.1、HTTP/2 还是 HTTP/3 连接。
  • HTTP协议相关的功能通过各HTTP过滤器实现,这些过滤器大体可分为编码器、解码器和编/解码器三类;

    • router (envoy.router)是最常的过滤器之一,它基于路由表完成请求的转发或重定向,以及处理重试操作和生成统计信息等;

路由表配置

每个HTTP 连接管理器过滤器都有一个关联的路由表。可以通过以下两种方式之一指定路由表:

  • 静态的。

  • 可经由xDS API中的RDS动态生成。

内建重试插件

重试行为

Host Predicates

  • 这些predicates 可用于“拒绝”主机,这将导致重新尝试主机选择。可以指定任意数量的这些predicates ,如果任何predicates 拒绝主机,则主机将被拒绝。
  • Envoy 支持以下内置host predicates
    • envoy.retry_host_predicates.previous_hosts:这将跟踪以前尝试过的主机,并拒绝已经尝试过的主机。

    • envoy.retry_host_predicates.omit_canary_hosts:这将拒绝任何被标记为金丝雀主机的主机。主机通过端点过滤器元数据中的过滤器设置来标记。
    • envoy.retry_host_predicates.omit_host_metadata:这将根据预定义的元数据匹配标准拒绝任何主机。

Priority Predicates

  • 这些predicates可用于调整在为重试尝试选择优先级时使用的优​​先级负载。只能指定一个这样的predicates。
  • Envoy 支持以下内置priority predicates
    • envoy.retry_priorities.previous_priorities:这将跟踪先前尝试的优先级,并调整优先级负载,以便在后续重试尝试中以其他优先级为目标。

重试插件配置示例

  • 例如,要将重试配置为首选尚未尝试过的主机, 可以使用内置predicates:envoy.retry_host_predicates.previous_hosts
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.previous_hosts
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
  host_selection_retry_max_attempts: 3

这将拒绝以前尝试过的主机,最多重试主机选择 3 次。为了处理不可能找到可接受的主机(没有主机满足predicates)或不太可能(唯一合适的主机具有非常低的相对权重)的情况,尝试限制是必要的。

  • 要根据其元数据拒绝主机,可以使用envoy.retry_host_predicates.omit_host_metadata
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.omit_host_metadata
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.omit_host_metadata.v3.OmitHostMetadataConfig
      metadata_match:
        filter_metadata:
          envoy.lb:
            key: value

这将拒绝任何在其元数据中匹配(键、值)的主机。

  • 要配置重试以在重试期间尝试其他优先级,可以使用内置envoy.retry_priorities.previous_priorities
retry_policy:
  retry_priority:
    name: envoy.retry_priorities.previous_priorities
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.priority.previous_priorities.v3.PreviousPrioritiesConfig
      update_frequency: 2

这将针对尚未使用的后续重试尝试中的优先级。该update_frequency参数决定了重新计算优先级负载的频率。

  • 这些插件可以组合,这将排除以前尝试过的主机以及以前尝试过的优先级。
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.previous_hosts
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
  host_selection_retry_max_attempts: 3
  retry_priority:
    name: envoy.retry_priorities.previous_priorities
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.priority.previous_priorities.v3.PreviousPrioritiesConfig
      update_frequency: 2

内部重定向

Envoy 支持在内部处理 3xx 重定向,即捕获可配置的 3xx 重定向响应,合成新请求,将其发送到新路由匹配指定的上游,并将重定向响应作为对原始请求的响应返回。原始请求的标头和正文将在重定向中发送到新位置。尚不支持预告片。

内部重定向通过路由配置中的内部重定向策略字段进行配置。当重定向处理打开时,来自上游的任何 3xx 响应,匹配 redirect_response_codes 都将受到 Envoy 正在处理的重定向的影响。

如果 Envoy 配置为内部重定向 HTTP 303 并接收到 HTTP 303 响应,如果原始请求不是 GET 或 HEAD 请求,它将使用无实体的 HTTP GET 分派重定向。否则,Envoy 将保留原始 HTTP 方法。有关详细信息,请参阅RFC 7231 第 6.4.4 节。

要成功处理重定向,它必须通过以下检查:

  1. 有一个与redirect_response_codes中的一个匹配的响应代码,它可以是 302(默认情况下),也可以是一组 3xx 代码(301、302、303、307、308)。

  2. 有一个带有有效、完全限定 URL的位置标头。

  3. 该请求必须已由 Envoy 完全处理。

  4. 请求必须小于per_request_buffer_limit_bytes限制。

  5. allow_cross_scheme_redirect为 true(默认为 false),或者下游请求的 scheme 和location头相同。

  6. 给定下游请求中先前处理的内部重定向的数量不超过 请求或重定向请求所命中的路由的最大内部重定向。

  7. 所有predicates都接受目标路由。

任何失败都将导致重定向被传递到下游。

由于重定向的请求可能会在不同的路由之间反弹,因此重定向链中的任何路由

  1. 没有启用内部重定向

  2. 或者当重定向链命中它时,最大内部重定向 小于或等于重定向链长度

  3. 或被任何predicates禁止

将导致重定向传递到下游。

两个predicates可用于创建定义重定向链、先前路由predicatesallow_listed_routes的 DAG 。具体来说,允许列出的路由predicates定义了 DAG 中各个节点的边,而先前的路由predicates定义了边的“已访问”状态,因此如果需要,可以避免循环。

第三个谓词safe_cross_scheme 可用于防止 HTTP -> HTTPS 重定向。

一旦重定向通过了这些检查,发送到原始上游的请求标头将通过以下方式修改:

  1. 将完全限定的原始请求 URL 放在 x-envoy-original-url 标头中。

  2. 用 Location 标头中的值替换 Authority/Host、Scheme 和 Path 标头。

然后,更改后的请求标头将选择一个新的路由,通过一个新的过滤器链发送,然后在所有正常的 Envoy 请求清理过程中向上游发送。

请注意,HTTP 连接管理器清理(例如清除不受信任的标头)只会应用一次。每个路由的标头修改都将应用于原始路由和第二个路由,即使它们相同,因此请小心配置标头修改规则以避免重复不需要的标头值。

示例重定向流程可能如下所示:

  1. 客户端向http://foo.com/bar发送 GET 请求

  2. 上游 1 发送带有 “位置:http://baz.com/eep”的 302

  3. Envoy 被配置为允许在原始路由上进行重定向,并向上游 2 发送一个新的 GET 请求,以获取带有附加请求标头 “x-envoy-original-url: http://”的http://baz.com/eep foo.com/bar”

  4. Envoy 将http://baz.com/eep的响应数据代理给客户端,作为对原始请求的响应。

超时

  • 支持适用于HTTP连接及其组成流(constituent streams)的多种可配置超时机制

    •  连接级别:空闲超时和排空超时(GOAWAY);
    •  流级别:空闲超时、每路由相关的上游端点超时和每路由相关的gRPC最大超时时长;

HTTP 标头清理

出于安全原因,HTTP 连接管理器执行各种标头清理操作。

参考文档

HTTP连接管理架构文档

https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http_connection_management

HTTP连接管理配置文档

https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/http_conn_man#config-http-conn-man

HTTP 标头清理文档

https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/header_sanitizing#config-http-conn-man-header-sanitizing

超时配置文档

https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts

posted @ 2022-08-30 14:39  小吉猫  阅读(236)  评论(0编辑  收藏  举报