HTTP 链接管理
对于基于服务的现代应用架构来说,HTTP是一个非常核心的组件,因此 Envoy 提供大量的针对HTTP的功能。Envoy 在网络层有一个过滤器叫做HTTP 链接管理器(HTTP connection manager)。该过滤器将字节流转化为 HTTP 层的消息和事件。(例如HTTP header 信息,body 信息和 trailer 信息)。它还处理所有 HTTP 连接和请求所共有的功能,如访问日志记录、请求 id 生成和跟踪、请求/响应 Header 操作、路由表管理和统计信息。
HTTP 协议
Envoy 的 HTTP 连接管理器支持 HTTP/1.1、WebSockets 和 HTTP/2 。它不支持 SPDY。Envoy 的 HTTP 支持首选为 HTTP/2 多路复用代理。在内部,HTTP/2 术语用于描述系统组件。例如,HTTP 请求和响应发生在流上,编解码器 API 用于将不同的协议相关的内容转换为用于流、请求、响应等与协议不相关的形式。在 HTTP/1.1 的情况下,编解码器将协议的串行/流水线功能转换为类似于 HTTP/2 的内容,将其转换为更高的层。这意味着大多数代码不需要了解流是源自 HTTP/1.1 还是 HTTP/2 连接。
HTTP Header 清理
出于安全原因, HTTP 连接管理器执行各种 HTTP Header 清理操作。
路由表配置
每个HTTP 连接管理器都被分配一个路由表。该路由表可以支持以下两种模式:
- 静态路由表
- 基于RDS API的动态路由表
重试插件配置
通常在重试过程中,主机选择遵循与原始请求相同的过程。若要修改此行为,可以使用重试插件,这些插件分为两类:
-
主机断言(Host Predicates):这些断言可用于 "拒绝" 主机,这将导致重新尝试选择主机。可以任意指定这些断言的数量,如果任何断言拒绝主机,则主机将被拒绝。
Envoy 支持以下内置主机断言- envoy.retry_host_predicates.previous_hosts: 这将跟踪以前尝试过的主机,并拒绝已尝试的主机。
-
优先级断言(Priority Predicates):这些断言可用于调整加载的优先级,这被用来决定重试时选择的顺序。只能指定一个这样的断言。
Envoy支持以下内置优先级断言- envoy.retry_priority.previous_priorities: 这将跟踪以前重试的顺序,并调整加载的优先级,以便在后续重试中用于其他优先级。
主机选择将持续执行,直到配置的断言接受主机或达到配置的最大重试次数。
这些插件可以组合在一起,以影响主机选择和加载的优先级。Envoy 还可以使用自定义重试插件进行扩展,类似于添加自定义过滤器。
配置示例:
例如配置一个重试机制,尝试从来没有连接过的主机,可以使用内置的envoy.retry_host_predicates.previous_hosts
断言。
retry_policy:
retry_host_predicate:
- name: envoy.retry_host_predicates.previous_hosts
host_selection_retry_max_attempts: 3
这条断言会拒绝之前已经尝试过的主机,并且最多尝试重连3次。尝试时的次数限制是必要的,以便处理在以下情况:找到一个可接受的主机是不可能的(没有主机满足断言) 或非常不可能的(唯一合适的主机具有非常低的相对权重)。
若要配置重试以在重试期间尝试其他优先级,可以使用内置的envoy.retry_host_predicates.previous_hosts
断言。
retry_policy:
retry_priority:
name: envoy.retry_priorities.previous_priorities
config:
update_frequency: 2
这将在后续的尝试中定位之前没有使用过的优先级。update_frequency
决定重新计算加载顺序的频率。
这些插件可以组合使用,用来排除之前使用过的主机和优先级:
retry_policy:
retry_host_predicate:
- name: envoy.retry_host_predicates.previous_hosts
host_selection_retry_max_attempts: 3
retry_priority:
name: envoy.retry_priorities.previous_priorities
config:
update_frequency: 2
内部重定向
Envoy 支持在内部处理302重定向,即捕获302重定向响应,生成新请求,将其发送到新路由匹配指定的上游目的地,并将重定向响应作为响应返回到原始请求。
内部重定向是通过路由配置中的 ref:redirect action <envoy_api_field_route.RouteAction.redirect_action>
字段配置。当重定向处理打开时,来自上游的任何302响应都受 Envoy 的重定向处理的影响。
要成功处理重定向, 必须通过以下检查:
- 是302个响应。
- 具有与原始请求的 Scheme 匹配的有效的、完全限定的 URL的Location Header。
- 这一请求必须是交给 Envoy 处理的。
- 请求不能有 body。
- 以前必须没有重定向请求, 这取决于是否存在 x-envoy-furl 标头。
任何 Envoy 无法处理的都会将重定向请求交给下游。
一旦重定向通过了这些检查,发送到原始上游的请求 header 将进行以下修改:
- 将完全限定的原始请求 url 放在 x-envoy-furl 标头中。
- 用 Location Header 中的值替换Authority/Host、Scheme 和 Path。
然后,更改后的请求标头将选择新的路由,通过新的过滤链发送,然后在进行所有正常 Envoy 请求清理的情况下向上游运输。
警告
请注意,HTTP 连接管理器清理 (如清除不受信任的Header) 将只应用一次。每个路由 Header 修改将同时应用于原始路由和第二次路由,即使它们是相同的,因此请小心配置标头修改规则,以避免重复不需要的标头值。
示例重定向流可能如下所示:
- 客户端发送 http://foo.com/bar 的 Get 请求
- 上游1发送一个302响应包含 “location: http://baz.com/eep”
- Envoy 配置为允许在原始路由上重定向,并向上游2发送新的附加 “x-envoy-original-url: http://foo.com/bar” 的 Get 请求,以获取 http://baz.com/eep 的内容。
- Envoy 将 http://baz.com/eep 的响应数据代理到客户端,作为对原始请求的响应。
超时
各种可配置的超时策略适用于 HTTP 连接及其组成流:
- 连接级空闲超时:这适用于没有任何流处于活动状态的空闲期间。
- 连接层流失超时:这发生在源于 GOAWAY 的 Enovy 和连接终止之间。
- 流级别空闲超时:这适用于每个单独的流。它可以在连接管理器和每个路由粒度进行配置。流上的 Header/data/trailer 事件会重置超时时间。
- 流级别的每个路由的上游超时:这适用于上游响应,即从下游请求结束到上游响应结束的时间的最大限制。这也可以在每次重试处指定。
- 流级别的每个路由 gRPC 最大超时:这限制了上游超时, 并允许通过 gRPC 超时请求 Header 重写超时。
网友评论