ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Envoy Thrift 代理内置过滤器全解析:Header-To-Metadata、Payload-To-Metadata、Rate Limit 与 Router

Envoy Thrift 代理内置过滤器全解析:Header-To-Metadata、Payload-To-Metadata、Rate Limit 与 Router Envoy Thrift 代理内置过滤器全解析Header-To-Metadata、Payload-To-Metadata、Rate Limit 与 Router【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoyEnvoy 的 Thrift 代理thrift_proxy是一组用于处理 Thrift 协议流量转发、路由与治理的网络过滤器链。本文以官方配置文档 thrift_filters.rst 为主线系统讲解 Envoy 内置的四个 Thrift 过滤器header_to_metadata、payload_to_metadata、rate_limit 与 router。读完本文你将掌握每个过滤器的 v3 配置方式、完整可运行的 YAML 示例、规则匹配语义、统计指标与动态元数据行为并能组合它们实现基于版本/负载特征的子集负载均衡subset load balancing、全局限流与精细化路由。Thrift 过滤器链概览Envoy 在 network 层面的envoy.filters.network.thrift_proxy过滤器中维护了一条独立的thrift_filters过滤器链。官方文档列出了四个内置过滤器过滤器v3 类型 URLtype.googleapis.com/...核心职责Header-To-Metadataenvoy.extensions.filters.network.thrift_proxy.filters.header_to_metadata.v3.HeaderToMetadata将 Thrift 请求头转换为动态元数据dynamic metadataPayload-To-Metadataenvoy.extensions.filters.network.thrift_proxy.filters.payload_to_metadata.v3.PayloadToMetadata将 Thrift 请求体字段转换为动态元数据Rate Limitenvoy.extensions.filters.network.thrift_proxy.filters.ratelimit.v3.RateLimit调用全局限流服务RLS实施流量限制Routerenvoy.extensions.filters.network.thrift_proxy.router.v3.Router依据路由表执行 Thrift 请求转发其中前三个过滤器本身不产生终端转发动作它们的产出动态元数据可供 Router 过滤器做子集负载均衡、路由匹配或被 Access Log 等下游消费方使用。在thrift_filters链中Router 通常是最后一个过滤器负责实际转发。Header-To-Metadata 过滤器把请求头变成负载均衡依据Header-To-Metadata 过滤器通过一组规则rule对请求头进行匹配。每条规则绑定一个具体的 header可以配置头存在on_present与头缺失on_missing两种触发分支当头存在时提取头的值并与指定的 key 组成元数据当头缺失时触发 on_missing 分支使用配置中指定的值写入元数据。生成的元数据可用于负载均衡决策、日志消费等场景。官方文档点名的典型用例是将某个请求头的值提取出来挂到请求的动态元数据上再用于匹配端点子集subset实现按版本路由。该配置在 header_to_metadata.proto 中定义过滤器实现位于 header_to_metadata_filter.cc 与 config.cc。完整配置示例按版本头路由以下完整示例取自文档所附配置 header-to-metadata-filter.yaml包含监听器、过滤器链与上游集群三部分可直接作为静态配置骨架使用static_resources: listeners: - address: socket_address: address: 0.0.0.0 port_value: 9090 filter_chains: - filters: - name: envoy.filters.network.thrift_proxy typed_config: type: type.googleapis.com/envoy.extensions.filters.network.thrift_proxy.v3.ThriftProxy stat_prefix: ingress_thrift route_config: name: local_route routes: - match: method_name: route: cluster: versioned-cluster thrift_filters: - name: envoy.filters.thrift.header_to_metadata typed_config: type: type.googleapis.com/envoy.extensions.filters.network.thrift_proxy.filters.header_to_metadata.v3.HeaderToMetadata request_rules: - header: x-version on_present: metadata_namespace: envoy.lb key: version type: STRING on_missing: metadata_namespace: envoy.lb key: default value: true type: STRING remove: false clusters: - name: versioned-cluster type: STRICT_DNS lb_policy: ROUND_ROBIN lb_subset_config: fallback_policy: NO_FALLBACK subset_selectors: - keys: - default - keys: - version load_assignment: cluster_name: versioned-cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 19090 metadata: filter_metadata: envoy.lb: default: true - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 19091 metadata: filter_metadata: envoy.lb: version: 1.0配置语义如下请求携带x-version头时取头的值写入envoy.lb命名空间下的versionkey类型为字符串随后与端点元数据中envoy.lb.version相匹配例如值为1.0的请求会被路由到127.0.0.1:19091请求缺失x-version头时写入envoy.lb.default true匹配标记为default: true的端点127.0.0.1:19090remove: false表示规则应用后不删除该头若置为true头会在提取后被移除防止敏感头部信息泄漏到上游。规则与值的详细语义来自 proto 定义在 header_to_metadata.proto 中每条Rule的字段与校验约束如下header要提取的头部名要求符合 HTTP 头名校验规则HTTP_HEADER_NAME非严格模式且长度至少为 1on_present/on_missing均为KeyValuePair。on_missing 分支的value必须非空proto 校验要求 min_len: 1源码 header_to_metadata_filter.cc 中同样强制Cannot specify on_missing rule with empty value因为缺失头时没有原始值可用remove是否在提取后删除该头。KeyValuePair的关键字段metadata_namespace元数据命名空间留空时使用过滤器自身命名空间。从源码看默认命名空间为envoy.filters.thrift.header_to_metadata见 header_to_metadata_filter.cc 的decideNamespace实现key命名空间内的键校验要求 min_len: 1value当用于 on_present 且非空时会用该值替代头的原始值两者都为空时头值原样使用当用于 on_missing 时必须提供非空值type值类型枚举ValueType支持STRING0、NUMBER1以及PROTOBUF_VALUE2值为序列化的google.protobuf.Value默认 STRINGencode编码方式ValueEncode支持NONE0与BASE641。BASE64 主要用于 STRING 与 PROTOBUF_VALUE以转义头中的非 ASCII 字符存储为元数据前会按此编码解码regex_value_rewriteRegexMatchAndSubstitute类型的正则匹配替换仅对 on_present 生效。正则匹配与替换如果头的值在写入动态元数据之前需要转换该过滤器支持正则匹配与替换。以下示例配置取自 header-to-metadata-filter-regex-substitution.yamlthrift_filters: - name: envoy.filters.thrift.header_to_metadata typed_config: type: type.googleapis.com/envoy.extensions.filters.network.thrift_proxy.filters.header_to_metadata.v3.HeaderToMetadata request_rules: - header: x-version on_present: metadata_namespace: envoy.lb key: cluster regex_value_rewrite: pattern: regex: ^/(cluster[\\d\\w-])/?.*$ substitution: \\1该规则把形如/cluster123/...的头值通过正则^/(cluster[\d\w-])/?.*$捕获第一组替换为cluster123后写入envoy.lb.cluster元数据。从源码可见正则替换对象在规则构造期即通过Matcher::RegexReplace::create编译见 header_to_metadata_filter.cc若正则不匹配或替换失败头值仍按原样使用。执行时机与统计过滤器在transportBegin阶段即消息传输开始、读到头信息时从MessageMetadata的请求头中提取值并写入动态元数据随后返回Continue继续过滤器链见 header_to_metadata_filter.cc。统计指标官方文档明确说明该过滤器目前不产生任何统计。Payload-To-Metadata 过滤器直接解析请求体字段Payload-To-Metadata 过滤器与 Header-To-Metadata 目标相似——把请求中的某个字段值提取为动态元数据用于子集负载均衡。其配置定义在 payload_to_metadata.proto。官方文档给出了引入该过滤器的两个关键理由传输限制像 framed transport 这类传输不支持 THeaders无法使用 header-to-metadata 过滤器从请求体直接取字段则不受此限制单一事实来源直接引用 payload 字段Envoy 不再依赖下游服务总是正确地把字段复制到 THeader从而保证数据源唯一、准确。field_selector用链表描述嵌套字段路径每个Rule通过field_selector指定要匹配的字段。FieldSelector本质是一个单向链表每个节点有name用于日志和id用于匹配child指向下一节点。链表整体对应一条从请求消息结构顶层开始向下的字段路径。从 payload_to_metadata.proto 可见字段校验规则name长度至少为 1id取值区间为[-32768, 32767]对应 Thrift 字段 id 的 16 位有符号范围。Rule还支持按method_name精确匹配方法名空字符串匹配任意方法或service_name匹配服务名前缀用于多路复用场景二选一作为匹配前置条件。触发语义当字段存在时触发on_present当字段缺失时触发on_missing特例一字段存在但未配置on_present则该规则不添加任何元数据特例二字段是空字符串时on_present与on_missing都不会触发即该规则不添加元数据。完整配置示例按版本 payload 路由以下示例取自 payload-to-metadata-filter.yamlstatic_resources: listeners: - address: socket_address: address: 0.0.0.0 port_value: 9090 filter_chains: - filters: - name: envoy.filters.network.thrift_proxy typed_config: type: type.googleapis.com/envoy.extensions.filters.network.thrift_proxy.v3.ThriftProxy stat_prefix: ingress_thrift route_config: name: local_route routes: - match: method_name: route: cluster: versioned-cluster thrift_filters: - name: envoy.filters.thrift.payload_to_metadata typed_config: type: type.googleapis.com/envoy.extensions.filters.network.thrift_proxy.filters.payload_to_metadata.v3.PayloadToMetadata request_rules: - method_name: foo field_selector: name: info id: 2 child: name: version id: 1 on_present: metadata_namespace: envoy.lb key: version on_missing: metadata_namespace: envoy.lb key: default value: unknown clusters: - name: versioned-cluster type: STRICT_DNS lb_policy: ROUND_ROBIN lb_subset_config: fallback_policy: NO_FALLBACK subset_selectors: - keys: - default - keys: - version load_assignment: cluster_name: versioned-cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 19090 metadata: filter_metadata: envoy.lb: default: true - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 19091 metadata: filter_metadata: envoy.lb: version: 1.0与之对应的 Thrift 请求结构取自官方文档示例为namespace py schemas.service struct Info { 1: string version } service Service { void foo(1: string data, 2: Info info); }field_selector链表info(id2) - version(id1)对应请求消息中foo方法的info结构体字段 id 2里的version字段字段 id 1。于是方法名为foo、info.version字段存在时其值被写入envoy.lb.version并匹配对应版本端点字段缺失时写入envoy.lb.default unknown匹配默认端点。注意KeyValuePair中value对 on_present 是可选的留空则使用字段原值非空则覆盖而对 on_missing 必须非空因为缺失字段没有原始值可用regex_value_rewrite仅用于 on_present行为与 header-to-metadata 过滤器一致见 payload_to_metadata.proto。已知限制与性能设计官方文档明确了以下三点限制与设计不支持容器类型当前 payload-to-metadata 过滤器不支持 list、set、map 等容器类型字段单值大小限制该过滤器写入的单条元数据值被限制为1024 字节payload passthrough负载透传过滤器设计上支持 payload 透传——只做一次反序列化并把解析结果元数据传给其他过滤器。负载均衡决策、日志消费与路由可以共用同一次解析结果同时由于解析发生在透传缓冲区中不需要重新序列化是性能最优的路径。文档也指出在 BufferView 落地之前目前仍存在一次冗余的缓冲区拷贝。此外如果过滤器链中某个环节不支持 payload 透传从性能角度考虑建议使用自定义的非透传过滤器来设置元数据。统计指标该过滤器目前同样不产生任何统计。Rate Limit 过滤器接入全局限流服务Rate Limit 过滤器在请求的 route 上配置了一个或多个rate_limits且与过滤器的 stage 设置匹配时会调用全局限流服务。全局限流架构背景可参考 docs/root/intro/arch_overview/other_features/global_rate_limiting.rst仓库文档arch_overview_global_rate_limit锚点对应章节。每份 rate limit 配置都会生成一个 descriptor 发送给限流服务因此一个请求可能对应多个 descriptor。配置字段来自 rate_limit.protorate_limit.proto 定义了过滤器主体配置domain请求中使用的限流域必填min_len: 1stage限流配置阶段号。过滤器只使用 RouteAction 中 stage 号匹配的限流配置默认 stage 为 0支持范围010含timeout限流服务 RPC 超时默认20msfailure_mode_deny限流服务无响应时的行为。为true时限流服务通信失败将不允许流量通过拒绝默认false即失败时放行rate_limit_service外部限流服务提供方配置若未指定对限流服务的调用会立即返回成功。超限与失败处理若限流服务被调用且任一 descriptor 的响应为 over limit超限Envoy 返回一个表示内部错误的 Thrift 应用异常application exception若调用限流服务出错或服务返回错误且failure_mode_deny为true同样返回内部错误应用异常。限流配置挂在路由的RouteAction.rate_limits上类型为repeated config.route.v3.RateLimit见 route.proto。文档特别提示如需按 Thrift 服务名或方法名做限流匹配可以在 RequestHeaders action 中指定头名:method-name。统计指标过滤器在cluster.route target cluster.ratelimit.*命名空间下输出统计名称类型描述okCounter限流服务返回 under limit 的总数errorCounter联系限流服务出错的总数over_limitCounter限流服务返回 over limit 的总数failure_mode_allowedCounter因failure_mode_deny为 false 而被放行的出错请求总数动态元数据仅当 gRPC 限流服务返回的CheckResponse携带了填充好的dynamic_metadata字段时该过滤器才会以不透明的google.protobuf.Struct形式发出动态元数据。Router 过滤器Thrift 转发核心Router 过滤器实现了 Thrift 转发几乎所有 Thrift 代理场景都会用到。它的核心职责是遵循配置的 route.proto 中的RouteConfiguration路由表执行转发。其自身配置极简——router.proto 仅有一个字段close_downstream_on_upstream_error布尔值默认true即在路由或上游连接出错时关闭下游连接。路由表关键要素route.proto从 route.proto 可以归纳路由表的关键结构理解这些有助于配合前三个过滤器使用RouteMatch支持method_name精确匹配空字符串匹配任意方法、service_name前缀匹配多路复用场景、invert反转匹配以及headers头部匹配仅适用于支持头的 Thrift transport/protocolRouteAction目标集群支持三种形式——固定cluster、按权重分配流量的weighted_clusters、按请求头cluster_header动态决定集群头缺失返回 unknown method 异常集群不存在返回 internal error 异常RouteAction.metadata_match子集负载均衡的端点元数据匹配条件键值放在envoy.lb元数据键下与前面两个 to-metadata 过滤器产出的envoy.lb命名空间元数据形成闭环RouteAction.rate_limits挂载限流配置供 rate limit 过滤器消费RouteAction.strip_service_name剥离方法名中的服务前缀如Service:method变成methodRouteAction.request_mirror_policies请求镜像shadow策略fire and forget 模式主集群不存在时不触发镜像。路由错误统计Router 过滤器在thrift.stat_prefix.*命名空间输出通用路由错误统计名称类型描述route_missingCounter未找到路由的请求总数unknown_clusterCounter路由指向未知集群的请求总数upstream_rq_maintenance_modeCounter目标集群处于维护模式的请求总数no_healthy_upstreamCounter无健康上游端点可用的请求总数shadow_request_submit_failureCounter镜像请求提交失败的总数集群级统计Router 还负责产生由路由到的上游集群衍生的集群级统计。这些统计使用底层 cluster scope因此以thrift命名空间作前缀名称类型描述thrift.upstream_rq_callCounterCall 消息类型的请求总数thrift.upstream_rq_onewayCounterOneway 消息类型的请求总数thrift.upstream_rq_invalid_typeCounter不支持的请求消息类型总数thrift.upstream_resp_replyCounterReply 消息类型的响应总数Success 与 Error 之和thrift.upstream_resp_successCounter视为 Success 的 Reply 总数thrift.upstream_resp_errorCounter视为 Error 的 Reply 总数thrift.upstream_resp_exceptionCounterException 消息类型的响应总数thrift.upstream_resp_exception_localCounter本地生成的 Exception 响应总数thrift.upstream_resp_exception_remoteCounter从远端收到的 Exception 响应总数thrift.upstream_resp_invalid_typeCounter不支持的响应消息类型总数thrift.upstream_resp_decoding_errorCounter解码出错响应总数thrift.upstream_rq_timeHistogram请求发出到响应完成的耗时含 oneway 消息thrift.upstream_rq_sizeHistogram每个上游的请求消息大小字节thrift.upstream_resp_sizeHistogram每个上游的响应消息大小字节thrift.upstream_cx_drain_closeCounter因排空draining关闭的上游连接总数thrift.downstream_cx_partial_response_closeCounter因部分响应关闭的下游连接总数thrift.downstream_cx_underflow_response_closeCounter因响应下溢关闭的下游连接总数thrift.upstream_resp_exception_local.overflowCounter连接池溢出导致本地生成的 Exception 响应总数thrift.upstream_resp_exception_local.local_connection_failureCounter本地连接失败导致本地生成的 Exception 响应总数thrift.upstream_resp_exception_local.remote_connection_failureCounter远端连接失败导致本地生成的 Exception 响应总数thrift.upstream_resp_exception_local.timeoutCounter创建新连接超时导致本地生成的 Exception 响应总数区域zone统计当本地服务通过--service-zone指定与上游集群如 EDS 发现都能提供服务区域信息时Envoy 会在cluster.name.zone.from_zone.to_zone.*命名空间下追踪名称类型描述thrift.upstream_resp_*Counter各类响应总数如 reply、success 等thrift.upstream_rq_timeHistogram请求耗时毫秒注意事项文档特别提醒请求与响应大小直方图包含协议升级期间发送与接收的数据但无效响应不计入响应大小直方图。四个过滤器如何协同工作综合官方文档与仓库代码可以勾勒出一条典型的 Thrift 治理流水线请求进入thrift_proxy网络过滤器后依次经过thrift_filters链header-to-metadata / payload-to-metadata 在链前部把头部或请求体字段提取为envoy.lb命名空间的动态元数据一次解析、多处复用rate limit 过滤器依据路由上 stage 匹配的限流配置向 RLS 发 descriptor超限即返回内部错误应用异常并可通过failure_mode_deny控制失败时的通断router 过滤器最后根据路由表、metadata_match与上游集群的lb_subset_config选择子集端点完成转发同时输出thrift.*系列统计。这种元数据注入 → 限流治理 → 子集路由的组合正是 Envoy 处理 Thrift 流量时最常用的落地形态。四个过滤器的完整官方说明可分别查阅 header_to_metadata_filter.rst、payload_to_metadata_filter.rst、rate_limit_filter.rst 与 router_filter.rst对应的 v3 API 定义位于 api/envoy/extensions/filters/network/thrift_proxy 目录下。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表