ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Envoy HTTP 健康检查过滤器(Health Check Filter)深入解析:配置、统计与源码实现

Envoy HTTP 健康检查过滤器(Health Check Filter)深入解析:配置、统计与源码实现 Envoy HTTP 健康检查过滤器Health Check Filter深入解析配置、统计与源码实现【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本指南以 Envoy 仓库中的 health_check_filter.rst 配置文档为核心系统讲解 HTTP 健康检查过滤器的四种工作模式透传、透传缓存、不透传、不透传集群健康计算、全部统计指标以及/healthcheck/fail管理端点与x-envoy-immediate-health-check-fail请求头的联动机制。读者读完将掌握该过滤器在服务网格场景下的配置方法、运维排障要点并能从源码层面理解其缓存与集群健康判定的实现原理。过滤器概览与适用场景在 Envoy 网格中当集群之间配置了主动健康检查active health checking时会产生大量健康检查流量。为了降低对本地服务的冲击Envoy 提供了一个HTTP 健康检查过滤器HTTP health checking filter可安装到配置好的 HTTP 监听器listener中由 Envoy 自身直接应答健康检查请求而不必每次都把请求转发给后端服务。该过滤器属于 HTTP 流过滤器stream filter在 HTTP 连接管理器HttpConnectionManager的过滤器链中工作扩展名称为envoy.filters.http.health_check。其配置通过 v3 类型 URLtype.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck下发对应 v3 API 定义v2 时代的HealthCheck消息类型已被保留并映射到 v3 版本见 proto 中的versioning注解。从架构上看该过滤器解决的核心问题是将健康检查从后端服务自报状态转变为Envoy 边缘直接裁决。这让前端代理front proxy能够独立于业务服务对外提供健康状态也便于在服务排空draining、灰度发布和重启维护时统一控制流量。四种工作模式依据 架构概览文档健康检查过滤器支持四种工作模式由配置项pass_through_mode与cache_time、cluster_min_healthy_percentages组合决定不透传No pass through健康检查请求永不转发到本地服务Envoy 根据服务器当前排空draining状态直接返回200或503。不透传 上游集群健康计算No pass through, computed from upstream cluster health过滤器依据一个或多个上游集群中健康 降级healthy degraded的主机占比是否达到cluster_min_healthy_percentages指定阈值返回200或503。若服务器处于排空状态则无论上游集群健康与否一律返回503。透传Pass through每个健康检查请求都会转发给本地服务由服务自身返回200或503。透传 缓存Pass through with caching请求会转发给本地服务但 Envoy 会将结果缓存一段可配置的时间缓存期间的健康检查请求直接返回缓存值缓存到期后下一个请求再次穿透到本地服务。这是大型网格部署时推荐的工作模式Envoy 对健康检查流量使用持久连接自身开销极小该模式能在不淹没本地服务的前提下提供对每个上游主机健康状态的最终一致视图。值得强调的是架构文档明确建议在大型网格中采用透传 缓存模式避免大量健康检查请求反复冲击业务服务。配置项详解v3 APIHealthCheck消息的完整字段定义位于 api/envoy/extensions/filters/http/health_check/v3/health_check.proto共四个可用字段字段类型必填/默认说明pass_through_modegoogle.protobuf.BoolValue必填指定过滤器是否工作在透传模式。对应 透传/透传缓存 与 不透传/不透传集群计算 两组模式的分界。cache_timegoogle.protobuf.Duration仅透传模式下有效缓存上游响应的时间毫秒。仅当pass_through_mode为 true 且值大于 0 时生效在非透传模式下设置会直接导致配置校验失败。cluster_min_healthy_percentagesmapstring, type.v3.Percent仅非透传模式指定若干上游集群名及每个集群中必须达到的健康 降级主机最小百分比全部达标才返回 200。配置的集群若不存在过滤器不会返回 200。百分比按截断取整计算例如 12.50% 按 12% 计算。headers重复的config.route.v3.HeaderMatcher可选健康检查请求的头部匹配规则。过滤器会将请求头部与所有指定头部逐一比对要指定健康检查端点可将:path头部设置为精确匹配路径。配置校验规则源码佐证在 config.cc 中可以看到以下关键校验逻辑pass_through_mode必须显式设置ASSERT(proto_config.has_pass_through_mode())非透传模式下若设置了cache_time工厂返回InvalidArgumentError错误信息原文为cache_time_ms must not be set when path_through_mode is disabled因此该字段在非透传模式被严格禁用非透传模式下才解析cluster_min_healthy_percentages若其中包含 NaN 值则同样拒绝加载配置cache_time的毫秒转换使用了PROTOBUF_GET_MS_OR_DEFAULT宏未设置时默认为 0当cache_time 0时创建共享的缓存管理器HealthCheckCacheManager。此外扩展通过LEGACY_REGISTER_FACTORY注册为具名 HTTP 过滤器工厂注册名为envoy.health_check旧名与扩展名envoy.filters.http.health_check见 config.cc 及 BUILD 中的envoy.filters.http.health_check扩展注册二者在配置中均可使用。完整配置示例仓库自带的配置文件为我们提供了两个可直接参考的真实示例。示例一前端代理——不透传模式configs/envoy_front_proxy.template.yaml 中前端代理对/healthcheck路径采用不透传模式直接由 Envoy 裁决http_filters: - name: envoy.filters.http.health_check typed_config: type: type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck pass_through_mode: false headers: - name: :path string_match: exact: /healthcheck - name: envoy.filters.http.buffer ... - name: envoy.filters.http.router该配置的核心要点pass_through_mode: false健康检查请求不会到达本地业务服务Envoy 依据自身排空状态直接返回 200/503headers中通过:path精确匹配/healthcheck从而定义健康检查端点注意此处使用的是HeaderMatcher的string_match精确匹配写法等价于 proto 定义中的HeaderMatcher字段该配置省略了cache_time与cluster_min_healthy_percentages属于纯不透传模式。示例二服务间通信——透传 缓存模式configs/envoy_service_to_service.template.yaml 则展示了透传 缓存的推荐实践http_filters: - name: envoy.filters.http.health_check typed_config: type: type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck pass_through_mode: true headers: - name: :path string_match: exact: /healthcheck cache_time: 2.5s - name: envoy.filters.http.router要点解析pass_through_mode: true配合cache_time: 2.5s健康检查请求每 2.5 秒最多穿透一次到本地服务其余请求由缓存直接应答既保证健康状态的新鲜度又显著降低服务负载headers同样以:path精确匹配/healthcheck作为健康检查端点下游的envoy.filters.http.router负责将非健康检查请求继续路由转发。结合集群健康计算的不透传示例若要启用不透传 上游集群健康计算可按 集成测试 中的写法配置name: health_check typed_config: type: type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck pass_through_mode: false cluster_min_healthy_percentages: example_cluster_name: { value: 75 }该配置要求名为example_cluster_name的集群中至少 75% 的主机处于健康或降级状态否则健康检查返回 503。对应测试ComputedHealthCheck验证了当该集群不存在/不健康时对/healthcheck的请求返回503见 health_check_integration_test.cc。底层实现原理过滤器主流程decodeHeaders → onComplete核心实现位于 health_check.cc入口是decodeHeaders第 53-78 行处理逻辑如下匹配请求用Http::HeaderUtility::matchHeaders(headers, *header_match_data_)将请求头与配置的headers逐一比对。若命中则标记health_check_request_ true调用callbacks_-streamInfo().healthCheck(true)将该请求标记为健康检查流量用于后续日志、追踪等行为的区分对追踪 span 调用setSampled(false)确保健康检查流量不会被上报到追踪后端避免健康检查请求污染 trace 数据决定是否接管handling_非透传模式、或服务器处于 healthCheckFailed 状态、或缓存命中useCachedResponse()为 true时过滤器接管该请求接管处理若end_stream且handling_为真调用onComplete()生成最终响应返回状态接管时返回FilterHeadersStatus::StopIteration停止向下游过滤器链传递否则返回Continue放行。响应裁决逻辑onCompleteonComplete第 117-200 行是裁决的核心其优先级如下服务器主动失败优先若context_.healthCheckFailed()即/healthcheck/fail管理端点被调用无论过滤器如何配置一律返回503并设置FailedLocalHealthCheck响应标志StreamInfo::CoreResponseFlag::FailedLocalHealthCheck缓存优先若配置了缓存管理器cache_manager_直接返回缓存的响应码与降级标志对应cached_response统计集群健康计算若配置了cluster_min_healthy_percentages遍历每个集群集群不存在 → 返回 503failed_cluster_not_found集群存在但成员为空 → 若最小健康百分比为 0 则跳过该集群继续检查否则返回 503failed_cluster_empty健康判定公式100 * (membership_healthy membership_degraded) membership_total * min_healthy_percentage时返回 503failed_cluster_unhealthy即健康 降级主机数占比低于阈值即判失败全部集群通过 → 返回 200兜底未命中以上任何分支且过滤器接管默认返回 200。最终通过callbacks_-sendLocalReply(final_status, , ...)发送本地响应若响应为降级状态degraded还会在响应头上设置x-envoy-degraded源码中headers.setEnvoyDegraded()。响应处理encodeHeadersencodeHeaders第 98-115 行在响应返回路径上做两件事若请求命中健康检查匹配health_check_request_则将本次响应码与降级状态写入缓存cache_manager_-setCachedResponse(...)并设置x-envoy-upstream-healthchecked-cluster响应头值为本地集群名便于 LB 与监控系统识别健康检查来源若服务器处于 healthCheckFailed 状态则在所有响应包括正常请求的响应上设置x-envoy-immediate-health-check-fail响应头。缓存机制HealthCheckCacheManagerhealth_check.h 中的HealthCheckCacheManager是按过滤器配置共享、跨线程共享的单例式缓存管理器其机制为通过事件分发器创建定时器clear_cache_timer_构造时立即触发onTimer()onTimer()将use_cached_response_置为 false并重新启用cache_time时长的定时器setCachedResponse(code, degraded)记录最近一次上游响应码与降级状态并将use_cached_response_置为 true缓存窗口到期后use_cached_response_恢复为 false下一个健康检查请求将重新穿透到本地服务。需要说明的是缓存失效时不保证只有单个请求穿透——在失效窗口期内可能会有若干请求同时打到后端见 health_check.h 的注释。这也是透传缓存属于最终一致视图的原因。相应地request_total统计同时覆盖由缓存直接应答与实际穿透的请求。与路由过滤器的联动x-envoy-immediate-health-check-fail如 health_check_filter.rst 的 note 所述一旦/healthcheck/fail管理端点被调用过滤器会在所有响应健康检查请求与普通请求上自动设置x-envoy-immediate-health-check-fail头/healthcheck/ok可逆转该行为。该头的消费方是路由过滤器router filter。按 router_filter.rst 的说明若上游主机返回该头设置为任意值Envoy 将立即认为该主机在主动健康检查中失败前提是集群配置了主动健康检查并将其从负载均衡中排除详见 排除机制文档。这允许通过标准数据面处理实现快速失败无需等待下一个健康检查周期主机可通过正常的主动健康检查恢复健康。这正是 架构文档 中active health checking fast failure主动健康检查快速失败机制的数据面基础。管理端点/healthcheck/fail 与 /healthcheck/ok对应 admin.rstPOST /healthcheck/fail使所有入站健康检查失败。无论过滤器如何配置透传等该操作都会普遍性地使健康检查请求失败适用于关闭服务器前的排空draining或全量重启POST /healthcheck/ok逆转/healthcheck/fail的效果。两者都要求 HTTP 健康检查过滤器已启用。这为运维提供了软排空能力先让 LB/上游把本节点从服务池摘除再从容执行下线或重启。统计指标过滤器在http.stat_prefix.health_check.命名空间下输出统计stat_prefix来自所属 HTTP 连接管理器的stat_prefix字段。统计结构定义于 health_check.h与配置文档一一对应名称类型说明request_totalCounter过滤器处理的请求总数包含由缓存直接应答的请求failedCounter失败的健康检查总数含因集群状态失败与缓存应答导致的失败okCounter通过的健康检查总数cached_responseCounter以缓存健康状态应答的请求总数failed_cluster_not_foundCounter因引用的集群不存在而失败的健康检查数failed_cluster_emptyCounter检查集群健康时因集群成员为空而失败的健康检查数failed_cluster_unhealthyCounter因集群健康主机比例低于最小阈值而失败的健康检查数degradedCounter报告降级degraded状态的健康检查响应数从源码看统计的埋点与判定分支一一对应health_check.ccrequest_total在onComplete中每次接管即自增failed在服务器主动失败分支与最终状态非 2xx分支各自增一次注意两分支的统计对象是同一个 counterok在最终状态为 2xx 时自增cached_response在命中缓存分支自增degraded在响应带降级标志时自增三个failed_cluster_*指标分别对应集群不存在、集群为空、健康占比不足三个子分支。借助这些指标如failed的突增、cached_response与request_total的比值运维可以快速判断健康检查失败是源于本地排空、集群缺失还是上游健康度不足。对应测试 health_check_test.cc 的CachedResponseStats等用例验证了缓存命中时cached_response统计的递增行为。最佳实践与注意事项综合配置文档、架构文档与源码实现落地该过滤器时有几点值得关注大型网格优先使用透传 缓存Envoy 对健康检查流量使用持久连接、处理成本极低配合缓存如cache_time: 2.5s即可在健康状态新鲜度与后端负载之间取得平衡避免健康检查风暴压垮业务服务。不透传模式的适用边界当 Envoy 作为前端代理、本身不承载业务服务时如 envoy_front_proxy.template.yaml用纯不透传让 Envoy 依据排空状态直接裁决即可需要代表上游集群健康度对外表态时再配置cluster_min_healthy_percentages。配置约束务必遵守cache_time与cluster_min_healthy_percentages均只在各自对应模式下生效非透传模式配置cache_time会导致过滤器工厂直接报错拒绝加载见 config.cc。百分比按整数截断cluster_min_healthy_percentages的百分比值在计算时被截断为整数12.50% 视为 12%配置阈值时应留出余量。健康检查请求的隔离命中健康检查匹配的请求会设置 streamInfo 的健康检查标记并关闭追踪采样因此健康检查流量不会污染业务追踪数据同时/healthcheck/fail会通过x-envoy-immediate-health-check-fail头联动路由过滤器实现上游快速摘除适用于灰度失败与节点排空场景。结合主动健康检查理解数据面联动该过滤器侧重入站健康检查应答本节点对外的健康状态与集群级出站主动健康检查Envoy 探测上游共同构成网格健康检查闭环x-envoy-immediate-health-check-fail头正是将两者衔接的桥梁详见 快速失败机制。延伸阅读健康检查架构总览主动/被动健康检查与过滤器的整体定位v3 API 参考HealthCheck 消息字段级完整定义与校验规则过滤器源码实现请求裁决与缓存逻辑过滤器配置工厂配置解析与校验管理接口文档/healthcheck/fail与/healthcheck/ok路由过滤器响应头说明x-envoy-immediate-health-check-fail的消费语义单元测试 与 集成测试验证缓存、统计与集群健康计算的测试用例【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表