IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【Ribbon】自定义负载均衡策略实现不同版本的灰度(金丝雀)发布 -> 正文阅读

[系统运维]【Ribbon】自定义负载均衡策略实现不同版本的灰度(金丝雀)发布

前言

灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度 —— 百度百科

📒 下面把上面这段表述抽象成程序设计模型:

比如现在有2个服务,user服务和order服务,user服务通过在注册中心拉取order服务的地址来消费order服务,灰度发布其实就是让v1版本的user去消费v1版本的order,让v2版本的user去消费v2版本的order。

Ribbon是一个Netflix公司开发的的负载均衡组件,通过自定义实现它的负载均衡策略,可以实现我们的需求。

1.配置负载均衡策略

Nacos中有实现一个优先访问同一ClusterName的Service的负载均衡策略NacosRule,我们可以参考其源码实现。

先上GrayReleasedRule的代码:

public class GrayReleasedRule extends AbstractLoadBalancerRule {

    private static final Logger LOGGER = LoggerFactory.getLogger(GrayReleasedRule.class);

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public Server choose(Object key) {
        try {
            String version = this.nacosDiscoveryProperties.getMetadata().get("version");
            DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
            String name = loadBalancer.getName();

            NamingService namingService = nacosDiscoveryProperties
                    .namingServiceInstance();
            List<Instance> instances = namingService.selectInstances(name, true);
            if (CollectionUtils.isEmpty(instances)) {
                LOGGER.warn("no instance in service {}", name);
                return null;
            }

            List<Instance> instancesToChoose = instances;

            if (StringUtils.isNotBlank(version)) {
                List<Instance> sameClusterInstances = instances.stream()
                        .filter(instance -> Objects.equals(version,
                                instance.getMetadata().get("version")))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(sameClusterInstances)) {
                    instancesToChoose = sameClusterInstances;
                }
                else {
                    LOGGER.warn(
                            "A version-service scall occurs,name = {}, version = {}, instance = {}",
                            name, version, instances);
                }
            }

            Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose);

            return new NacosServer(instance);
        }
        catch (Exception e) {
            LOGGER.warn("GrayReleasedRule error", e);
            return null;
        }
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }

}

首先我们需要继承一个AbstractLoadBalancerRule抽象类,它实现了IRule接口,我们需要实现它的choose(Object key)方法,关键部分的代码我把它摘出来:

 if (StringUtils.isNotBlank(version)) {
                List<Instance> sameClusterInstances = instances.stream()
                        .filter(instance -> Objects.equals(version,
                                instance.getMetadata().get("version")))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(sameClusterInstances)) {
                    instancesToChoose = sameClusterInstances;
                }
                else {
                    LOGGER.warn(
                            "A version-service scall occurs,name = {}, version = {}, instance = {}",
                            name, version, instances);
                }
            }

我选用的注册中心是Nacos,整合到SpringCloud使用,所以我在
在yml配置文件上的元数据metadata字段中配上version字段

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8888
        metadata:
          version: v1

首先获取到我们配置的版本号version

String version = this.nacosDiscoveryProperties.getMetadata().get("version");

判断从注册中心获取的version不为空的时候,判断是否和当前服务的版本号相同,相同的话就去访问同一版本号的服务。

总结,只需要建立多套服务实例,配置不同的版本号,选择目标用户群体,让请求分散到不同版本号的入口服务上,就能实现不同版本服务的隔离。

2.指定负载均衡策略

通过SpringBean生成策略返回一个IRule接口类型的实例交给SpringContainer管理,覆盖掉Ribbon的默认生成策略

@Configuration
public class RibbonGrayReleasedConfig {
    public IRule ribbonRule() {
        return new GrayReleasedRule();
    }
}

补充:Ribbon负载均衡策略

在这里插入图片描述
1.RandomRule: 随机选择一个Server。
2.RetryRule: 对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server。
3.RoundRobinRule: 轮询选择, 轮询index,选择index对应位置的Server。
4.AvailabilityFilteringRule: 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就是检查status里记录的各个Server的运行状态。
5.BestAvailableRule: 选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过。
6.WeightedResponseTimeRule: 根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低。
7.ZoneAvoidanceRule: 默认的负载均衡策略,即复合判断Server所在区域的性能和Server的可用性选择Server,在没有区域的环境下,类似于轮询(RandomRule)
8.NacosRule(Nacos的自定义实现): 同集群优先调用

有兴趣的可以自行测试

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 22:36:33  更:2022-03-11 22:36:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 3:28:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码