ARTICLE DETAIL

资讯详情

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

Envoy 区域感知路由(Zone Aware Routing):机制、前提条件与源码实现解析

Envoy 区域感知路由(Zone Aware Routing):机制、前提条件与源码实现解析 Envoy 区域感知路由Zone Aware Routing机制、前提条件与源码实现解析【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy在跨可用区zone部署的服务网格中Envoy 需要在上游集群的不同 zone 间智能分配流量既希望把请求尽量发给本 zone 的上游主机以降低跨区延迟又不能让某个 zone 过载。本文围绕 Envoy 官方架构文档 zone aware routing 展开完整覆盖其术语定义、生效前提、两类比例关系下的路由决策并结合 ZoneAwareLoadBalancerBase 实现 与 运行时参数文档 深入剖析百分比计算、残差容量采样和 panic 联动等底层细节。核心术语在讨论 Envoy 的区域感知路由之前先统一以下三个术语与官方文档一致Originating cluster / Upstream cluster源集群 / 上游集群Envoy 把请求从 originating cluster 路由到 upstream cluster。前者是承载本地 Envoy 自身的集群后者是被负载均衡的目标集群。Local zone本区域同时包含 originating cluster 一部分主机和 upstream cluster 一部分主机的同一个 zone。Zone aware routing区域感知路由尽力best effort地把请求路由到 upstream cluster 中位于 local zone 的主机。目的在尽量把流量推向上游集群本地 zone 的同时大致维持上游集群所有主机之间每秒请求数RPS的均衡具体均衡程度取决于所用负载均衡策略。生效前提条件区域感知路由并非默认无条件生效源码中的 earlyExitNonLocalityRouting 对应了文档中列出的前提条件originating cluster 和 upstream cluster 都未处于 panic 模式。Panic 机制详见 Panic threshold 文档默认阈值为 50%运行时键upstream.healthy_panic_threshold。当某一侧集群可用主机占比过低时区域感知路由会被跳过——源码中如果 local cluster 处于 panic会递增统计计数器lb_local_cluster_not_ok_并回退到普通的健康主机选择见 hostSourceToUse。区域感知路由被显式开启。默认是开启的100%可被运行时参数覆盖upstream.zone_routing.enabled路由到同一上游 zone 的请求百分比默认 100%upstream.zone_routing.min_cluster_size允许尝试区域感知路由的上游集群最小规模默认6。集群健康主机数小于该值时直接跳过区域路由并递增lb_zone_cluster_too_small_计数器upstream.zone_routing.force_local_zone.min_size配合配置中的force_local_zone使用当 local zone 内上游健康主机数达到该值时强制走 LocalityDirect 模式全部流量直发本 zone。以上三个键在 load_balancer_impl.cc 中定义并在 cluster_runtime.rst 中有正式说明。上游集群主机数量足够即不满足小型集群跳过条件见上一条的min_cluster_size。此外从源码结构看还有两个隐含前提earlyExitNonLocalityRouting要求上游集群的healthyHostsPerLocality()至少有2 个 localitylocal cluster 中必须存在位于当前 Envoy 所在 locality 的主机否则说明 local cluster 配置有误无法进行有意义的比例计算。两类比例关系下的路由决策Envoy 是否把某次请求路由到 local zone、还是走跨区路由取决于 originating cluster 与 upstream cluster 在 local zone 内的健康主机占比关系。官方文档归纳为两种情况这与源码中 regenerateLocalityRoutingStructures 计算出的三种路由状态NoLocalityRouting/LocalityDirect/LocalityResidual一一对应情况一源集群本 zone 占比高于上游集群设 local zone 在 originating cluster 中的健康主机占比为 local_percentage、在 upstream cluster 中为 upstream_percentage两者均按 10000 缩放存储见 calculateLocalityPercentages。当 local_percentage upstream_percentage 时不可能把 local zone 的全部请求都打到上游 local zone否则会造成上游主机间请求量失衡。此时 Envoy计算可以直发 local zone 的流量比例local_percent_to_route_ upstream_percentage / local_percentage源码示例local 20%、upstream 10%则只有 50% 的请求可直发命中的请求走 local zone状态LocalityResidual下每次选主前用random() % 10000 local_percent_to_route_判定见 tryChooseLocalLocalityHosts未命中的请求走跨区路由具体选哪个 zone依据各 zone 的残差容量residual capacity即该 zone 上游占比减去源占比后的富余能力。残差容量按累积和方式构成采样桶Envoy 在总残差容量内取随机阈值再线性扫描定位目标 zone从而让跨区流量按各 zone 富余容量成比例地分配——容量为 0 的 zone 不会被选中。源码中的注释给出了一个直观例子local_percentage 为 40%/40%/20%×10000 缩放upstream_percentage 为 25%/50%/25% 时残差容量为 0/10000/5000累积后是 0/10000/15000极端情况下若总残差容量因取整误差为 0则随机选一个 zone并递增lb_zone_no_capacity_left_统计。情况二源集群本 zone 占比低于上游集群此时 upstream cluster 的 local zone 不仅能承接 originating cluster local zone 的全部请求还富余出空间接纳来自其他 zone 的流量如果其他 zone 的 Envoy 需要。对应源码逻辑当upstream_percentage local_percentage时状态被置为LocalityDirect所有请求直接路由到 local zoneregenerateLocalityRoutingStructures。若启用force_local_zone_min_size则只要 local zone 健康主机数达到阈值也直接进入LocalityDirect。这两种决策在 stats 上可以被直接观察lb_zone_routing_all_directly_LocalityDirect、lb_zone_routing_sampled_残差命中 local、lb_zone_routing_cross_zone_跨区、lb_zone_no_capacity_left_无残差容量。源码视角的实现细节路由状态只在 P0 上生效官方文档末尾明确当使用多个优先级priority时区域感知路由目前仅支持 P0。从源码结构看这一点体现得很直接resizePerPriorityState 中为 P!0 创建的PerPriorityState永远是NoLocalityRouting注释写明Note for P!0, PerPriorityState is created with NoLocalityRouting and never changedZoneAwareLoadBalancerBase 构造函数 还断言 local_priority_set 只有 1 个 host set因为要正确支持多优先级就得对所有本地 Envoy 同时故障切换做假设。local cluster 成员变化时只会重新生成 P0 的路由结构。百分比如何计算calculateLocalityPercentages 对 local 与 upstream 两侧分别按 locality 聚合权重默认基准HEALTHY_HOSTS_NUM健康主机个数配置为HEALTHY_HOSTS_WEIGHT时改用主机权重之和结果乘以 10000 缩放为整数以便后续整型采样。如果某个上游 locality 没有主机其 upstream_percentage 为 0local_percentage 也不再有意义同样置 0。触发重新计算的时机区域路由结构不是每次选主都重算而是在集群成员变化时批量刷新构造函数中注册了addPriorityUpdateCb回调当 P0 变化或 local cluster 成员更新时调用regenerateLocalityRoutingStructures并递增lb_recalculate_zone_structures_统计。值得注意的是文档注释指出这些比例与该优先级承接多少总负载是正交的——即使所有集群一半主机变不健康P0 仍会把一半负载发给 local zone、80% 发给残差区同一优先级内部跨 locality 的公平性有保证但跨优先级之间不保证。与 panic 模式的关系hostSourceToUse中可以看到完整的判定顺序先看所选优先级是否 panicpanic 时默认用全部主机或在配置了fail_traffic_on_panic时直接丢弃流量再看upstream.zone_routing.enabled运行时开关是否放行本次选主再检查 local cluster 是否 panic最后才调用tryChooseLocalLocalityHosts决定 locality 索引。这解释了为什么两侧集群都不在 panic是区域路由生效的硬前提。可观测性与验证手段排查区域感知路由行为时建议关注统计计数器lb_recalculate_zone_structures_结构重算次数、lb_zone_routing_all_directly_/lb_zone_routing_sampled_/lb_zone_routing_cross_zone_/lb_zone_no_capacity_left_、lb_local_cluster_not_ok_、lb_zone_cluster_too_small_运行时键upstream.zone_routing.enabled灰度关闭区域路由而不改配置、upstream.zone_routing.min_cluster_size、upstream.healthy_panic_threshold行为级测试仓库提供了 zone aware 负载均衡器的 fuzz 测试基类以及围绕 round robin / random 等策略的 负载均衡模拟测试可作为理解流量按残差容量成比例分布这一不变式的参考验证。小结Envoy 的区域感知路由本质上是一个比例守恒问题按 local zone 在两侧集群中的健康占比关系要么全量直发 local zoneLocalityDirect要么按upstream/local比例直发、其余按残差容量成比例跨区分流LocalityResidual。它只在 P0、双侧集群非 panic、且集群规模不小于min_cluster_size默认 6时生效且全程 best effort——任何前提不满足都会静默回退到普通负载均衡不影响可用性。理解 ZoneAwareLoadBalancerBase 的这套状态机后配合 stats 计数器就能在真实部署中精确解释每一次请求为什么去了这个 zone。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表