HTTP 路由
Envoy 包含一个 HTTP 路由过滤器,可以安装它来执行高级路由任务。
这对于处理边缘流量(传统的反向代理请求处理)以及构建服务到服务 Envoy 网格(通常通过路由到主机/授权 HTTP 标头以到达特定上游服务集群)都很有用。
Envoy 还可以配置为正向代理。在正向代理配置中,网格客户端可以通过适当地配置其 HTTP 代理为 Envoy 来参与。
在高层次上,路由器接收传入的 HTTP 请求,将其与上游集群匹配,获取与上游集群中的主机的 连接池,然后转发请求。
路由过滤器支持许多功能,包括
- 虚拟主机和集群
将域/授权映射到一组路由规则。
虚拟集群在虚拟主机级别指定,并由 Envoy 用于在标准集群级别统计数据之上生成其他统计数据。虚拟集群可以使用正则表达式匹配。
- 路径、前缀和标头匹配
根据大小写 敏感 和不区分大小写的 前缀和精确请求路径进行路由,或者使用 正则表达式路径匹配 以及更复杂的匹配规则。
根据 任意标头 匹配路由。
- 路径、前缀和主机重写
重写 前缀,或 使用正则表达式和捕获组的路径。
- 请求重定向
-
TLS 重定向 在虚拟主机级别。
- 请求超时、重试和对冲
请求重试 可以通过 HTTP 标头或路由配置来指定。
Envoy 还提供 请求对冲 用于对请求(每次尝试)超时进行重试。
- 流量转移和拆分
通过 运行时值 将流量从一个上游集群转移到另一个上游集群,或者根据 基于权重/百分比的路由 在多个上游集群之间拆分流量(请参阅 流量转移/拆分)。
- 基于策略的路由
- 直接响应
非代理 HTTP 响应 在路由级别。
- 绝对 URL
绝对 URL 支持非 TLS 正向代理。
路由范围
范围路由使 Envoy 能够对域和路由规则的搜索空间进行限制。
对于每个请求,HTTP 连接管理器都会动态计算范围键以选择 路由表。
RouteConfiguration 与范围相关联,可以使用 OnDemand 过滤器配置。
The Scoped RDS (SRDS) API 包含一组 范围 资源,每个资源定义独立的路由配置,以及 ScopeKeyBuilder 定义 Envoy 用于查找与每个请求对应的范围的键构建算法。
在以下(静态配置的)范围路由示例中,Envoy 将通过 ;
拆分 Addr
标头值,通过 =
拆分它们来确定键值对,并将找到的第一个值为 x-foo-key
的键作为范围键。
具体来说,如果 Addr
标头值为 foo=1;x-foo-key=bar;x-bar-key=something-else
,那么 bar
将被计算为范围键以查找相应的路由配置。
11 typed_config:
12 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
13 stat_prefix: ingress_http
14 codec_type: AUTO
15 http_filters:
16 - name: envoy.filters.http.router
17 typed_config:
18 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19 scoped_routes:
20 name: scope_by_addr
21 scope_key_builder:
22 fragments:
23 - header_value_extractor:
24 name: Addr
25 element_separator: ";"
26 element:
27 key: x-foo-key
28 separator: "="
29 scoped_route_configurations_list:
30 scoped_route_configurations:
31 - on_demand: true
32 name: scoped_route_0
33 key:
34 fragments:
35 - string_key: bar
36 route_configuration:
37 name: local_route
38 virtual_hosts:
39 - name: local_service
40 domains: ["*"]
41 routes:
42 - match:
43 prefix: "/"
44 route:
45 cluster: cluster_0
要使键与 ScopedRouteConfiguration 匹配,构建的键中的片段数量必须与 ScopedRouteConfiguration 中的片段数量匹配。然后按顺序匹配片段。
注意
构建的键中缺少的片段(被视为 NULL
)使请求无法匹配任何范围,即无法为请求找到任何路由条目。
路由表
HTTP 连接管理器的 配置 拥有 路由表,该路由表由所有配置的 HTTP 过滤器使用。
尽管路由过滤器是路由表的主要消费者,但其他过滤器也可以访问它,以防它们希望根据请求的最终目的地做出决策。例如,内置的速率限制过滤器会查询路由表,以确定是否应根据路由调用全局速率限制服务。
连接管理器确保对获取路由的所有调用对于特定请求都是稳定的,即使决策涉及随机性(例如,在运行时配置路由规则的情况下)。
重试语义
Envoy 允许在 路由配置 中以及通过 请求标头 为特定请求配置重试。
以下是可能的配置
- 最大重试次数
Envoy 将继续重试任何次数。
重试之间的间隔由指数退避算法(默认值)决定,或者根据上游服务器通过标头提供的反馈(如果存在)决定。
注意
所有重试都包含在总体请求超时内。
这避免了由于大量重试导致的长时间请求。
- 重试条件
Envoy 可以在不同的条件类型上进行重试,具体取决于应用程序要求。例如,网络故障、所有 5xx 响应代码、幂等的 4xx 响应代码等。
- 重试预算
Envoy 可以通过 重试预算 限制可以重试的活动请求的比例,以防止它们导致流量大幅度增加。
- 主机选择重试插件
Envoy 可以配置为在为重试选择主机时应用额外的逻辑。
指定 重试主机谓词 允许在选择特定主机时重新尝试主机选择(例如,当已尝试过的主机被选中时),而 重试优先级 可以配置为调整在选择重试的优先级时使用的优先级负载。
注意
当 x-envoy-overloaded 存在时,Envoy 会重试请求。建议配置 重试预算(优先) 或设置 最大活动重试断路器 为适当的值,以避免重试风暴。
请求对冲
Envoy 支持请求对冲,可以通过指定 对冲策略 来启用。
这意味着 Envoy 将竞速多个同时的 upstream 请求,并返回具有可接受的 headers 的第一个响应给 downstream。
重试策略用于确定是否应该返回响应或是否应该等待更多响应。
目前,对冲只能在响应请求超时时执行。这意味着将发出重试请求,而不会取消初始的超时请求,并且会等待延迟响应。第一个符合重试策略的“良好”响应将返回给 downstream。
这种实现确保了不会对同一个 upstream 请求重试两次,否则可能会发生这种情况:如果一个请求超时然后导致 5xx 响应,从而产生两个可重试的事件。
优先级路由
Envoy 在 路由 级别支持优先级路由。
当前的优先级实现为每个优先级级别使用不同的 连接池 和 断路器 设置,这意味着即使对于 HTTP/2 请求,也会使用两个物理连接连接到 upstream 主机。
当前支持的优先级是 default
和 high
。
直接响应
Envoy 支持发送“直接”响应。这些是预先配置的 HTTP 响应,不需要代理到 upstream 服务器。
在路由中指定直接响应有两种方法。
设置 direct_response 字段。这适用于所有 HTTP 响应状态。
设置 redirect 字段。这仅适用于重定向响应状态,但它简化了
Location
标头的设置。
直接响应具有 HTTP 状态代码和可选的正文。
路由配置可以内联指定响应正文,也可以指定包含正文的文件路径。
如果路由配置指定了文件路径名,Envoy 将在配置加载时读取文件并缓存内容。
注意
如果指定了响应正文,默认情况下,它的大小限制为 4KB,无论它是内联提供还是在文件中提供。
Envoy 目前将整个正文保存在内存中,因此 4KB 默认值旨在防止代理的内存占用过大。
如果需要,可以通过设置 max_direct_response_body_size_bytes 字段来更改此限制。
如果为路由或包含的虚拟主机设置了 response_headers_to_add
,Envoy 将在直接 HTTP 响应中包含指定的标头。
通过泛型匹配进行路由
Envoy 支持使用 泛型匹配树 来指定路由表。
这比原始匹配引擎更具表现力,允许对任意标头进行次线性匹配(与原始匹配引擎不同,原始匹配引擎只能对某些情况下的 :authority
执行此操作)。
要使用泛型匹配树,请在虚拟主机上指定一个匹配器,并将 路由 或 路由列表 作为操作
11 typed_config:
12 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
13 stat_prefix: ingress_http
14 codec_type: AUTO
15 http_filters:
16 - name: envoy.filters.http.router
17 typed_config:
18 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19 route_config:
20 name: local_route
21 virtual_hosts:
22 - name: local_service
23 domains: ["*"]
24 matcher:
25 matcher_tree:
26 input:
27 name: request-headers
28 typed_config:
29 "@type": type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
30 header_name: :path
31 exact_match_map:
32 map:
33 "/new_endpoint/foo":
34 action:
35 name: route_foo
36 typed_config:
37 "@type": type.googleapis.com/envoy.config.route.v3.Route
38 match:
39 prefix: /foo
40 route:
41 cluster: cluster_0
42 request_headers_to_add:
43 - header:
44 key: x-route-header
45 value: new-value
46 "/new_endpoint/bar":
47 action:
48 name: route_bar
49 typed_config:
50 "@type": type.googleapis.com/envoy.config.route.v3.Route
51 match:
52 prefix: /bar
53 route:
54 cluster: cluster_1
55 request_headers_to_add:
56 - header:
57 key: x-route-header
58 value: new-value
59
60 "/new_endpoint/baz":
61 action:
62 name: route_list
63 typed_config:
64 "@type": type.googleapis.com/envoy.config.route.v3.RouteList
65 routes:
66 - match:
67 prefix: /baz
68 headers:
69 - name: x-match-header
70 string_match:
71 exact: foo
72 route:
73 cluster: cluster_2
74 - match:
75 prefix: /baz
76 headers:
77 - name: x-match-header
78 string_match:
79 exact: bar
80 route:
81 cluster: cluster_3
82
83 clusters:
这允许使用泛型匹配框架提供的额外匹配灵活性来解析用于基于 routes
的路由的相同的 路由
proto 消息。
注意
生成的 路由 还指定了匹配条件。
为了实现路由匹配,必须满足此条件才能解析路由。
当使用路径重写时,匹配的路径仅取决于解析的 路由 的匹配条件。
在匹配树遍历期间完成的路径匹配不会影响路径重写。
唯一支持的输入是请求标头(通过 HttpRequestHeaderMatchInput)。
提示
有关 API 全部的更多信息,请参阅 匹配 API 文档。