0%

Envoy 如何选择上游

作为一个 Proxy 软件,选择代理的目标上游地址,是最基本的功能。
同时,也需要足够灵活的路由选址策略支持,才能满足各种的业务诉求。

同 Nginx 一样,Envoy 也分为两步:

  1. 先选择 cluster
  2. 再从 cluster 选择 Host

选择 cluster

Envoy 是在 route action 里面完成 cluster 指定的,有这么几种方式:

  1. cluster,直接指定 cluster name

  2. cluster_header,通过读取一个 header 的值来获取 cluster name

  3. weighted_clusters,从一组 cluster 中按照权重选取一个

  4. cluster_specifier_plugin,通过额外的 plugin 来获得 cluster name

    这是 Envoy 提供的一种扩展方式,可以自己实现 plugin 来自定义的选择 cluster

选择 Host

cluster 包含了一批 host,从中选择哪一个,则是由 loadbalancer 来完成了。

Envoy 内置了很多个 balancer,比如常见都有:

  1. 随机
  2. 权重轮询
  3. Maglev 一致性哈希

这些常见的 balancer 侧重于负载均衡,但是还缺少了一些业务语义的灵活支持。 比如:

  1. 就近选择
  2. 灰度,等各种发布策略

所以,Envoy 又提供了 Locality 和 subset 两种筛选机制,这里简单介绍下 subset

Load Balancer Subsets

Subset 是一种从 cluster 中匹配 Host 的很灵活的算法

基本流程是:

  1. Host 可以有打标数据,通常是字符串的 key=>value 对
  2. route 可以指定 key=>value 的过滤条件,来筛选 Host

具体可以看 Envoy 官网上的示例

Subset 匹配条件

之所以,说它很灵活,主要是:

  1. 打标数据可以是任意的 key=>value 对,而且可以多个
  2. 用来匹配的 key=>value 条件,可以是 route 级别指定,还可以由 http filter 来动态设置

最终进行 Subset 匹配的条件,是由 route action 的 metadata,和 http filter 动态设置的 dynamicmetadata 合并而来的。这样的话 http filter 就可以通过设置匹配过滤条件,来灵活的指定筛选效果了

MOE 的优势

Envoy 已经通过动态配置,实现了 cluster/Host 这种元数据的动态更新。

但是,在不同的业务场景下,我们还是需要灵活的自定义的选择策略。对此,MOE 还是提供了两层的灵活控制:

动态选择 cluster

比如:

  1. 容灾场景,需要切换机房
  2. 安全场景,比如发现是攻击请求,引流到蜜罐

这些场景,通过 cluster 内选择 Host,是不太合适的

所以,我们计划提供实现 cluster_specifier_plugin 扩展 ,这样我们就可以,用 Go 代码来实现任意的 cluster 选择策略了。

动态选择 Host

subset 已经是很灵活匹配策略了,MOE 则是计划提供,在 Go 里面动态设置匹配条件 ,以最大程度的释放 Subset 的灵活性。

怎么样,心动了不?如果你有类似的需求,或者对实现感兴趣,欢迎跟我们联系