首页 > 其他分享 >使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)

使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)

时间:2024-01-04 11:36:02浏览次数:40  
标签:金丝雀 环境 selectServiceInstances instance 发布 version 灰度

介绍

工作中经常要涉及到功能发布,这个时候也经常是业务系统最有可能遇到问题的时候,需要要尽量减少发布引起的风险。比如在系统负载比较小的时候使用。还有蓝绿发布、灰度发布等等,今天介绍一下这几种常见的发布,并使用springcloud 实现。

1.传统发布方式

一个系统最初的时候,使用量小,用户少,系统也是单体架构,有时候连系统挂了都没有人发现,这个时候常见的上线新功能就是替换包,然后重启服务。

使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)_新功能

这种方式最简单,也最方便,适合很多小型项目,但是也有一定的缺陷,在服务发布的过程中。系统是不能对外提供服务的。最严重的问题是,如果新功能发布失败,可能会导致长时间不可用。所以为了尽量减少在发布的过程中对用户的影响。提升系统的可用性。我们需要引入更好的发布方法。

2.常见的发布方式

我们在工作中经常遇到这种问题,一个新功能在测试环境运行的很好,测试也测了好几遍都是正常的,但是在生产环境一部署就不行了,不是启动失败,就是功能逻辑不对。这个是由于环境的差异造成的。毕竟生产环境很复杂,用的人也多。为了减少这种情况对业务系统的影响,我们可以引入蓝绿发布。

蓝绿发布

使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)_新功能_02

蓝绿发布的流程如上图所示,我们把生产环境的系统分为2部分,1套绿环境,1套蓝环境,绿环境是线上正在运行的v1版本,我们现在要发布新的v2版本,具体的操作如下:

  1. 生产的所有用户的流量都切换为绿环境,不经过蓝环境。
  2. 蓝环境的版本升级为v2,然后让测试测试蓝环境的功能。
  3. 确定蓝环境没有功能问题时,可以先将少部分生产的流量切到蓝环境。运行正常后,将所有的生产流量切换为蓝环境。
  4. 将绿环境的版本升级为v2。再将所有的生产的流量都切换为绿环境,至此,发布完成。

不像之前的直接发布方式,蓝绿发布可以解决大部分因为发布新功能导致的问题。测试也有条件去测试生产环境的功能了,在测试的过程中不用担心新功能对生产用户造成的影响。

优点:

  • 升级过程无需停机,用户感知小
  • 升级过程一半资源提供服务
  • 升级/回滚速度快

缺点:

  • 如果出了问题,影响面较广

蓝绿发布中,如果业务在测试生产环境没有发现问题,等到完全升级完成之后才发现问题,比如多发了优惠券,接口有bug等等,这个时候对系统的影响就很大了。为了尽量减少这种情况的影响。我们可以使用灰度发布。

灰度发布

使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)_生产环境_03

灰度发布也叫金丝雀发布。

金丝雀发布由来:以前矿工开矿,在下矿洞前需要检查下方是否有毒气,矿工们先会放一只金丝雀进去探是否有毒气体,看金丝雀能否活下来。

灰度发布(金丝雀发布)主要是为了减少发布过程中的问题对用户的影响,主要流程如上图所示,如果要发布v2版本,先发布一部分节点,导入一部分生产环境的流量,然后再逐步增加,如果发现问题,可以及时修复,这样在发布过程中的问题,可以尽量少的影响用户体验。

优点:

  • 风险控制:灰度发布可以降低新版本引入生产环境时的风险。通过逐步引入新功能,团队可以更容易地发现和解决潜在的问题,而不会对整个用户群体造成影响。
  • 反馈循环:通过逐步引入新版本,团队可以及时获取用户反馈,从而更好地了解新功能的表现和用户体验。这有助于及时调整和改进新功能。
  • 逐步推广:灰度发布允许团队逐步将新版本引入到整个用户群体中,从而更好地控制资源和性能的负载。这有助于避免突然的流量激增和性能问题。

缺点:

  • 部署复杂性:灰度发布需要更复杂的部署和管理流程。需要确保新版本可以与旧版本和灰度版本共存,并且需要确保灰度流量的正确路由和控制。
  • 增加开发时间:由于需要逐步引入新版本,灰度发布可能会增加整个发布周期的时间。这可能会对产品的快速迭代和更新速度产生影响。
  • 管理成本:灰度发布需要更多的管理和监控成本,包括对不同版本的流量和性能进行监控,以及对灰度发布过程中的问题进行跟踪和解决。

3. 蓝绿灰度发布的实现

现在主流的微服务接口调用为springcloud + nacos,下面我以这个技术栈来实现一下动态的蓝绿发布和灰度发布。

主要的技术点有以下:

  1. 如何标记服务为蓝绿环境

服务标记可以利用nacos的元数据 metadata:

spring:
  application:
    name: provider1
  cloud:
    nacos:
      discovery:
        # nacos 注册地址
        server-addr: localhost:8848
        # nacos 元数据,标记版本和环境
        metadata:
          version: green-v1
      config:
        server-addr: localhost:8848
server:
  port: 8001

使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)_灰度_04

  1. 如何获取不同环境的服务 springcloud 可以通过 继承 DelegatingServiceInstanceListSupplier 类来获取某个服务上面注册中心的所有节点,然后可以通过 nacos 的元数据进行过滤,这样就可以区分蓝绿环境的服务了。

获取注册的服务列表:

Flux<List<ServiceInstance>> listFlux = delegate.get(request);

根据消费者的环境来获取生产者的环境:

private List<ServiceInstance> filteredByVersion(List<ServiceInstance> instances, String version) {

        for (ServiceInstance instance : instances) {
            log.info("==> 服务:[{}]在注册中心的实例信息:[{}]", getServiceId(), writeValueAsString(instance));
        }

        // 1、获取 请求头中的 version 和 ServiceInstance 中 元数据中 version 一致的服务
        List<ServiceInstance> selectServiceInstances = instances.stream()
                .filter(instance -> instance.getMetadata().get(VERSION_HEADER_NAME) != null
                        && Objects.equals(version, instance.getMetadata().get(VERSION_HEADER_NAME)))
                .collect(Collectors.toList());
        if (!selectServiceInstances.isEmpty()) {
            log.info("返回请求服务:[{}]为version:[{}]的有:[{}]个", getServiceId(), version, selectServiceInstances.size());
            for (ServiceInstance instance : selectServiceInstances) {
                log.info("==> 服务:[{}]根据version过滤选择实例信息:[{}]", getServiceId(), writeValueAsString(instance));
            }
            return selectServiceInstances;
        }

        // 2、返回 versinotallow=default 的实例
        selectServiceInstances = instances.stream()
                .filter(instance -> Objects.equals(instance.getMetadata().get(VERSION_HEADER_NAME), "default"))
                .collect(Collectors.toList());
        log.info("返回请求服务:[{}]为version:[{}]的有:[{}]个", getServiceId(), "default", selectServiceInstances.size());
        for (ServiceInstance instance : selectServiceInstances) {
            log.info("==> 服务:[{}]根据version过滤选择实例信息:[{}]", getServiceId(), writeValueAsString(instance));
        }

        if (!selectServiceInstances.isEmpty()) {
            log.info("返回请求服务:[{}]为version:[{}]的有:[{}]个", getServiceId(), version, selectServiceInstances.size());
            for (ServiceInstance instance : selectServiceInstances) {
                log.info("==> 服务:[{}]根据version过滤选择实例信息:[{}]", getServiceId(), writeValueAsString(instance));
            }
            return selectServiceInstances;
        }

        return instances;
    }

从请求头中获取version 字段来确定版本,实际生产中可以根据自己的需求来确定规则,比如根据用户账号进行hash。

public void apply(RequestTemplate requestTemplate) {
        String version = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
                .getHeader("version");
        log.info("feign 中传递的 version 请求头的值为:[{}]", version);
        requestTemplate
                .header("version", version);
    }

请求蓝环境v2接口进行测试:

wget --no-check-certificate --quiet \
  --method GET \
  --timeout=0 \
  --header 'version: blue-v2' \
   'http://localhost:7001/consumer/consumer1/test1'

调用结果:

请求绿环境v1接口进行测试:

wget --no-check-certificate --quiet \
  --method GET \
  --timeout=0 \
  --header 'version: green-v1' \
   'http://localhost:7001/consumer/consumer1/test1'

调用结果:

灰度发布的原理类似,不同的地方是灰度发布需要逐步切换生产流量到新版本,可以通过nacos 修改服务的权重来实现。

4. 代码地址

springcloud nacos 实现蓝绿发布,灰度发布

https://gitee.com/yangzheng1/springcloud-deploy



标签:金丝雀,环境,selectServiceInstances,instance,发布,version,灰度
From: https://blog.51cto.com/u_64214/9097520

相关文章

  • Apple Xcode 14.3 (14E222b) 正式版发布下载
    CommandLineToolsforXcode14,tvOS16&watchOS9SimulatorRuntime作者主页:sysin.orgXcode14包含了在所有Apple平台上开发、测试和分发App所需的一切资源。利用Swift和SwiftUI的易用性与强大能力以及全新的跨平台App体验,使用编辑器的增强功能更快捷地编写代码......
  • CentOS 8.5 (2111) 发布 -- 最后一代 CentOS
    作者主页:sysin.org没想到Redhat还继续发布了CentOS8.5,并提醒您不应该在生产中使用CentOSLinux8。生命周期仍然是年底结束(End-of-life31December2021)。对于CentOS8.5看看就好,请速迁移到AlmaLinux或者RockyLinux。我们很高兴地宣布最新的CentOSLinux8版本。立即......
  • 跨集群流量调度实现 Kubernetes 集群金丝雀升级
    有了多集群服务和跨集群的流量调度之后,使用Kubernetes的方式会发生很大的变化。流量的管理不再限制单一集群内,而是横向跨越了多个集群。最重要的是这一切“静悄悄地”发生,对应用来说毫无感知。就拿Kubernetes版本升级来说吧。记得曾经经历过集群的原地升级:团队的几个人经过多次......
  • macOS Monterey 12.0.1 (21A559) 正式版发布,ISO、IPSW、PKG 下载
    本站下载的macOSMonterey软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。2021年10月26日,macOSMonterey正式版于今天凌晨推送,大版本升级建议全新安装。本站提供完整版iso镜像下载,可以用于全新安装或者升级,也可以直......
  • 鸿蒙原生应用/元服务开发-发布基础类型通知类型与接口
    基础类型通知主要应用于发送短信息、提示信息、广告推送等,支持普通文本类型、长文本类型、多行文本类型和图片类型。表 基础类型通知中的内容分类目前系统仅通知栏订阅了通知,将通知显示在通知栏里。基础类型通知呈现效果示意图如下所示。图1基础类型通知呈现效果示意图接口说明:通......
  • Visual Studio 2022 for Mac v17.0 发布,离线安装包下载
    为Mac打造的.NETIDE2022年5月23日,印度微软公布了VisualStudio2022forMacv17.0正式版发布(GA)的消息,并且现在可以下载了。这是迄今为止最快的VisualStudioforMac版本(sysin),具有全新的原生macOSUI,完全在.NET6上运行,并针对AppleSilicon(ARM64)处理......
  • Windows 11 简体中文版、英文版(64-bit、ARM64)下载(2022 年 1 月发布)
    Windows11最新正式版,2021年12月更新作者主页:www.sysin.org全新推出Windows11全新Windows体验,让您与热爱的人和事物离得更近。获得全新视角Windows11提供一个让人平静而富有创意的空间,全新体验引导您全力追逐热爱。从焕然一新的开始菜单,到与您关心的人、关注的消息、游戏......
  • Windows Server 2022 英文版、简体中文版下载 (updated Dec 2021)(2022 年 1 月发布)
    WindowsServer2022正式版,2021年12月更新2021.09.01更新,微软官方确认该版本为正式版:WindowsServer2022nowgenerallyavailable—deliversinnovationinsecurity,hybrid,andcontainers2021.08.19,微软在VLSC和MSDN发上发布了WindowsServer2022镜像下载,虽然并......
  • JetBrains GoLand 2023.2 (macOS, Linux, Windows) 发布 - Go Full Stack
    JetBrainsGoLand2023.2(macOS,Linux,Windows)发布-GoFullStack作者主页:sysin.orgJetBrainsGoLand-GoFullStackGo语言全栈IDE,对JavaScript、TypeScript和数据库提供扩展支持为何选择GoLand强大的代码洞察GoLand使读取、写入和更改Go代码变得非常容易实时错误......
  • macOS Monterey 12.6.8 (21G725) 正式版发布,ISO、IPSW、PKG 下载
    macOSMonterey12.6.8(21G725)正式版发布,ISO、IPSW、PKG下载本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。2023年7月24日(北京时间25日凌晨),App......