Envoy 的过滤器链是怎么工作的?顺序会改变结果吗?router 为什么必须在最后?怎么让某条路由不被限流?每多一个过滤器要多花多少延迟?这篇用 Envoy 1.39.3 逐项量出来。
过滤器顺序 | 200 | 429(被限流) | 503(被故障注入中止) | 合计 ------------------------------------+-----+----------+--------------+---- (a)fault → local_ratelimit → router | 98 | 99 | 203 | 400 (b)local_ratelimit → fault → router | 49 | 301 | 50 | 400 请求按顺序依次经过每个过滤器,谁先处理就先作用:故障注入在前时,被中止的请求(503)根本没有走到限流,不消耗令牌;限流在前时所有请求(包括之后会被中止的)都先消耗令牌,所以令牌更早用完,429 更多、通过的请求更少
请求按顺序经过每个过滤器,先处理的先起作用;故障注入和限流谁在前会改变通过的请求数。
启动结果:][critical][main] [source/server/server.cc:453] error `Error: terminal filter named envoy.filters.http.router of type envoy.filters.http.router must be the last filter in a http filter chain.` initializing config 'goo.gle/debugstr | Error: terminal filter named envoy.filters.http.router of type envoy.filters.http.router must be the last filter in a http filter chain. router 是 “终结过滤器”(它把请求转给上游并结束过滤器链),它后面不能再有别的过滤器;Envoy 在加载配置时就检查并拒绝
router 是终结过滤器,后面不能再有别的过滤器,Envoy 在加载配置时就拒绝。
路径 | 200 | 429 ------------------------+-----+---- /api(用过滤器级配置:5 个/秒) | 19 | 281 /health(路由级覆盖:1000 个/秒) | 300 | 0 路由级的 typed_per_filter_config 覆盖了过滤器自己的配置:同一个过滤器在不同路由上可以有不同的限流参数,健康检查之类的路径可以不被限流
typed_per_filter_config 让同一个过滤器在不同路由上用不同的参数。
router 之前的 Lua 过滤器个数 | 延迟 p50(ms) | 延迟 p99(ms) | p50 相对没有 Lua 过滤器多出的微秒
---------------------+------------+------------+----------------------
0 | 0.158 | 0.256 | +0
5 | 0.166 | 0.282 | +8
20 | 0.209 | 0.651 | +51
过滤器链里每多一个过滤器,每个请求都要多经过一次;Lua 过滤器要进入脚本虚拟机,开销比纯 C++ 的过滤器大。这里测的是一个很简单的脚本,真实的脚本越复杂开销越大
ERRORS {}每个过滤器都有成本,Lua 过滤器更贵;20 个简单脚本让 p50 多 51 µs。