作为一个 Proxy 软件,选择代理的目标上游地址,是最基本的功能。
同时,也需要足够灵活的路由选址策略支持,才能满足各种的业务诉求。
同 Nginx 一样,Envoy 也分为两步:
- 先选择 cluster
- 再从 cluster 选择 Host
选择 cluster
Envoy 是在 route action 里面完成 cluster 指定的,有这么几种方式:
cluster
,直接指定 cluster namecluster_header
,通过读取一个 header 的值来获取 cluster nameweighted_clusters
,从一组 cluster 中按照权重选取一个cluster_specifier_plugin
,通过额外的 plugin 来获得 cluster name这是 Envoy 提供的一种扩展方式,可以自己实现 plugin 来自定义的选择 cluster
选择 Host
cluster 包含了一批 host,从中选择哪一个,则是由 loadbalancer 来完成了。
Envoy 内置了很多个 balancer,比如常见都有:
- 随机
- 权重轮询
- Maglev 一致性哈希
这些常见的 balancer 侧重于负载均衡,但是还缺少了一些业务语义的灵活支持。 比如:
- 就近选择
- 灰度,等各种发布策略
所以,Envoy 又提供了 Locality 和 subset 两种筛选机制,这里简单介绍下 subset
Load Balancer Subsets
Subset 是一种从 cluster 中匹配 Host 的很灵活的算法
基本流程是:
- Host 可以有打标数据,通常是字符串的 key=>value 对
- route 可以指定 key=>value 的过滤条件,来筛选 Host
具体可以看 Envoy 官网上的示例
Subset 匹配条件
之所以,说它很灵活,主要是:
- 打标数据可以是任意的 key=>value 对,而且可以多个
- 用来匹配的 key=>value 条件,可以是 route 级别指定,还可以由 http filter 来动态设置
最终进行 Subset 匹配的条件,是由 route action 的 metadata,和 http filter 动态设置的 dynamicmetadata 合并而来的。这样的话 http filter 就可以通过设置匹配过滤条件,来灵活的指定筛选效果了
MOE 的优势
Envoy 已经通过动态配置,实现了 cluster/Host 这种元数据的动态更新。
但是,在不同的业务场景下,我们还是需要灵活的自定义的选择策略。对此,MOE 还是提供了两层的灵活控制:
动态选择 cluster
比如:
- 容灾场景,需要切换机房
- 安全场景,比如发现是攻击请求,引流到蜜罐
这些场景,通过 cluster 内选择 Host,是不太合适的
所以,我们计划提供实现 cluster_specifier_plugin 扩展 ,这样我们就可以,用 Go 代码来实现任意的 cluster 选择策略了。
动态选择 Host
subset 已经是很灵活匹配策略了,MOE 则是计划提供,在 Go 里面动态设置匹配条件 ,以最大程度的释放 Subset 的灵活性。
怎么样,心动了不?如果你有类似的需求,或者对实现感兴趣,欢迎跟我们联系