【Envoy 数据面】HTTP filter 链与 Router:顺序语义、终端过滤器与重试超时落点
内容提要
Envoy HTTP过滤器链中,Router必须是最后一个终端过滤器,其后的过滤器不会生效。重试和超时配置在路由策略中,由Router执行,总超时包含所有重试,默认不重试。常见误配包括过滤器顺序错误、重试无预算限制等,需注意授权过滤器与路由缓存的一致性。
延伸解读
过滤器顺序的常见误区
很多运维问题源于过滤器顺序错误,尤其是把鉴权或改头过滤器放在Router之后。这会导致这些过滤器完全不生效,因为Router必须是最后一个终端过滤器。配置时需确保Router位于http_filters列表末尾,否则后续过滤器不会参与请求处理。
重试与超时的配置要点
重试和超时配置在路由策略中,由Router执行。总超时包含所有重试,是外层时限;per-try超时是单次尝试时限。默认不重试,需显式配置retry_policy。重试会受cluster的max retries熔断和retry budget限制,溢出时可能返回503或标记x-envoy-overloaded。
路由缓存与鉴权一致性
HCM在过滤器链开始时缓存路由,后续过滤器可修改路由缓存,但Router最终确定目标。若鉴权过滤器依赖当前路由,而其后的过滤器清除了路由缓存,可能导致鉴权与实际路由不一致。应调整过滤器顺序或禁止清缓存,确保鉴权决策与最终路由一致。
Q&A
Envoy HTTP过滤器链中,过滤器顺序和终端过滤器有什么要求?
Decoder过滤器按配置顺序调用,Encoder过滤器按逆序调用。最后一个过滤器必须是终端过滤器,实践中几乎总是Router。写在Router之后的过滤器不会生效。
为什么把过滤器写在Envoy的Router过滤器之后不会生效?
因为Router是终端过滤器,写在它之后的过滤器既不会出现在decoder路径上,也不会参与响应编码,所以不会生效。常见症状是Lua、ext_authz或header改写不执行。
Envoy中重试和超时配置在哪里?总超时和per-try超时有什么区别?
重试和超时配置在Route/VirtualHost的policy中,由Router执行。总超时包含所有重试,是外层时限;per-try超时是单次上游尝试时限。总超时3s、首次尝试耗掉2.7s,则剩余重试只剩约0.3s。
Envoy默认会重试吗?重试会受什么限制?
默认不重试。重试会受cluster的max retries熔断和retry budget限制,溢出时计数upstream_rq_retry_overflow并可能打上x-envoy-overloaded。
Envoy中鉴权过滤器(如RBAC、ExtAuthz)与路由缓存有什么关系?
如果鉴权过滤器依赖当前route,而其后的Lua或ext_proc等过滤器又clearRouteCache(),则鉴权看到的route与最终Router看到的可能不一致。应调整顺序或禁止清缓存。
Envoy的Hedging策略是什么?有什么限制?
Hedging允许在per-try超时时再发一次上游请求而不取消原请求,取首个可接受响应。当前仅对per-try超时路径实现,且保证同一上游请求不会重复计成两次独立可重试事件。
Envoy中常见的重试和超时误配有哪些?
常见误配包括:Filter写在Router之后、只配retry_on不配超时边界、对非幂等写操作开5xx重试、授权filter在清route cache的filter之前。
Envoy中no_route和no_cluster统计分别代表什么?
no_route统计对应404,表示路由表缺条目;no_cluster统计默认对应503,表示cluster名不存在。它们是两条失败轴,不要和上游503混为一谈。