Spring Cloud 优雅下线以及灰度发布

2023-05-16

文章目录

    • 前言
    • 优雅下线
      • 常见的下线方式
      • 优雅的下线方式
    • 灰度发布
      • 蓝绿部署
      • 滚动部署
      • 金丝雀部署

前言

在生产环境中,如何保证在服务升级的时候,不影响用户的体验,这个是一个非常重要的问题。如果在我们升级服务的时候,会造成一段时间内的服务不可用,这就是不够优雅的。那什么是优雅的呢?主要就是指在服务升级的时候,不中断整个服务,让用户无感知,进而不会影响用户的体验,这就是优雅的。

实际上,优雅下线是目标,而不是手段,它是一个相对的概念,例如kill PIDkill -9 PID都是暴力杀死服务,相对于kill -9 PID来说,kill PID就是优雅的。但如果单独拿kill PID出来说,我们能说它是优雅的下线策略吗?肯定不是啊,就是这个道理。

因此,本文讲述的优雅下线仅能称之为“相对的优雅下线”,但相对于暴力的杀死服务,已经足够优雅了。常见的优雅解决方案,主要包括优雅下线和灰度发布。而实际上,灰度发布的范围就已经包含优雅下线了。最后,在本文中,我们主要讲述基于 Spring Cloud 和 Euraka 的优雅下线以及灰度发布。

优雅下线

常见的下线方式

方式一:kill PID

使用方式:kill java进程ID

该方式借助的是 Spring Boot 应用的 Shutdown hook,应用本身的下线也是优雅的,但如果你的服务发现组件使用的是 Eureka,那么默认最长会有 90 秒的延迟,其他应用才会感知到该服务下线,这意味着:该实例下线后的 90 秒内,其他服务仍然可能调用到这个已下线的实例。因此,该方式是不够优雅的 。

方式二:/shutdown端点

Spring Boot 提供了/shutdown端点,可以借助它实现优雅停机。

使用方式:在想下线应用的applicationyml中添加如下配置,从而启用并暴露/shutdown端点:

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown

发送 POST 请求到/shutdown端点

  • curl -X http://你想停止的服务地址/actuator/shutdown

该方式本质和方式一是一样的,也是借助 Spring Boot 应用的 Shutdown hook 去实现的。

方式三:/pause端点

Spring Boot 应用提供了/pause端点,利用该端点可实现优雅下线。

使用方式:在想下线应用的application.yml中添加配置,从而启用并暴露/pause端点:

management:
  endpoint:
    # 启用pause端点
    pause:
      enabled: true
    # 启用restart端点,之所以要启用restart端点,是因为pause端点的启用依赖restart端点的启用
    restart:
      enabled: true
  endpoints:
    web:
      exposure:
        include: pause,restart

发送 POST 请求到/actuator/pause端点:

  • curl -X POST http://你想停止的服务实例地址/actuator/pause

执行后的效果类似下图:

down
如图所示,该应用在 Eureka Server 上的状已被标记为DOWN,但是应用本身其实依然是可以正常对外服务的。在 Spring Cloud 中,Ribbon 做负载均衡时,只会负载到标记为UP的实例上。利用这两点,你可以:先用/pause端点,将要下线的应用标记为DOWN,但不去真正停止应用;然后过一定的时间(例如 90 秒,或者自己做个监控,看当前实例的流量变成 0 后)再去停止应用,例如kill应用。

  • 缺点 & 局限
缺点描述
不同的版本配置不大一样早期的 Spring Cloud 版本中,pause端点是不依赖restart端点的
无法和 Eureka 的健康检查配合使用如果你的服务发现组件用的是 Eureka,并且你的应用开启了健康检查eureka.client.healthcheck.enabled = true,那么/pause端点无效

方式四:/service-registry端点

使用方式:在想下线应用的application.yml中添加配置,从而暴露/service-registry端点:

management:
  endpoints:
    web:
      exposure:
        include: service-registry

发送 POST 请求到/actuator/service-registry端点:

curl -X "POST" "http://localhost:8000/actuator/service-registry?status=DOWN" \
   -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"

实行后的效果类似如下图:
down

优雅的下线方式

在上文中,我们讲述了四种常见的下线方式,对比来看,方式四 是一种比较优雅的下线方式。

在实际项目中,我们可以先使用/service-registry端点,将服务标记为DOWN,然后监控服务的流量,当流量为 0 时,即可升级该服务。当然,这里假设我们部署了多个服务实例,当一个服务实例DOWN掉之后,其他服务实例仍然是可以提供服务的,如果就部署一台服务的话,那么讨论优不优雅就没那么重要了。

除了上述的下线方式之外,还有一种利用EurekaAutoServiceRegistration对象达到优雅下线的目标。

  • 执行eurekaAutoServiceRegistration.start()方法时,当前服务向 Eureka 注册中心注册服务;
  • 执行eurekaAutoServiceRegistration.stop()方法时,当前服务会向 Eureka 注册中心进行反注册,注册中心收到请求后,会将此服务从注册列表中删除。

示例代码如下:

@RestController
@RequestMapping(value = "/graceful/registry-service")
public class GracefulOffline {

    @Autowired
    private EurekaAutoServiceRegistration eurekaAutoServiceRegistration;

    @RequestMapping("/online")
    public String online() {
        this.eurekaAutoServiceRegistration.start();
        return "execute online method, online success.";
    }

    @RequestMapping("/offline")
    public String offline() {
        this.eurekaAutoServiceRegistration.stop();
        return "execute offline method, offline success.";
    }
}

到这里,我们已经介绍了两种相对优雅的下线方式了。具体如何操作,我们可以根据实际上情况进行包装,或者利用自动化的脚本来实现更加优雅的下线方式。

灰度发布

蓝绿部署

蓝绿部署,英文名为 Blue Green Deployment,是一种可以保证系统在不间断提供服务的情况下上线的部署方式。

如何保证系统不间断提供服务呢?那就是同时部署两个集群,但仅对外提供一个集群的服务,当需要升级时,切换集群进行升级。蓝绿部署无需停机,并且风险较小。其大致步骤为:

  1. 部署集群 1 的应用(初始状态),将所有外部请求的流量都打到这个集群上
  2. 部署集群 2 的应用,集群 2 的代码与集群 1 不同,如新功能或者 Bug 修复等
  3. 将流量从集群 1 切换到集群 2
  4. 如集群 2 测试正常,就删除集群 1 正在使用的资源(例如实例),使用集群 2 对外提供服务

因为在使用蓝绿部署的方式时,我们需要控制流量,所以我们需要借助路由服务,如 Nginx 等。

滚动部署

滚动部署,英文名为 Rolling Update,同样是一种可以保证系统在不间断提供服务的情况下上线的部署方式。和蓝绿部署不同的是,滚动部署对外提供服务的版本并不是非此即彼,而是在更细的粒度下平滑完成版本的升级。

如何做到细粒度平滑升级版本呢?滚动部署只需要一个集群,集群下的不同节点可以独立进行版本升级。比如在一个 12 节点的集群中,我们每次升级 4 个节点,并将升级后的节点重新投入使用,周而复始,直到集群中所有的节点都更新为新版本。

这种部署方式相对于蓝绿部署,更加节约资源,因为它不需要运行两个集群。但这种方式也有很多缺点,例如:

  1. 没有一个确定 OK 的环境。使用蓝绿部署,我们能够清晰地知道老版本是 OK 的,而使用滚动发布,我们无法确定。
  2. 修改了现有的环境。
  3. 如果需要回滚,很困难。举个例子,在某一次发布中,我们需要更新 100 个实例,每次更新 10 个实例,每次部署需要 5 分钟。当滚动发布到第 80 个实例时,发现了问题,需要回滚。这时,我们估计就要疯了。
  4. 有的时候,我们还可能对系统进行动态伸缩,如果部署期间,系统自动扩容/缩容了,我们还需判断到底哪个节点使用的是哪个代码。尽管有一些自动化的运维工具,但是依然令人心惊胆战。

并不是说滚动发布不好,滚动发布也有它非常合适的场景。

金丝雀部署

金丝雀部署又称灰度部署(或者,灰度发布),英文名为 Canary Deployment,是指在黑与白之间,能够平滑过渡的一种发布方式。

金丝雀的名称来源于「矿井中的金丝雀」,早在 17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感,空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。

我们来看一下金丝雀部署的步骤:

  1. 准备好部署各个阶段的工件,包括:构建工件,测试脚本,配置文件和部署清单文件
  2. 从负载均衡列表中移除掉“金丝雀”服务器
  3. 升级“金丝雀”应用(切断原有流量并进行部署)
  4. 对应用进行自动化测试
  5. 将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)
  6. 如果“金丝雀”在线使用测试成功,升级剩余的其他服务器(否则就回滚)

在金丝雀部署中,常常按照用户量设置路由权重,例如 90% 的用户维持使用老版本,10% 的用户尝鲜新版本。不同版本应用共存,经常与 A/B 测试一起使用,用于测试选择多种方案。金丝雀部署比较典型的例子,就是我们在使用某个应用的时候,该应用邀请我们进行“内测”或者“新版本体验”,如果我们同意了,那么我们就成了金丝雀。


参考资料

  • 实用技巧:Spring Cloud中,如何优雅下线微服务?
  • Spring cloud系列20 实现服务优雅上下线
  • Spring Cloud 灰度发布解决方案
  • 一文搞懂蓝绿部署和金丝雀发布
  • 微服务部署:蓝绿部署、滚动部署、灰度发布、金丝雀发布
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Cloud 优雅下线以及灰度发布 的相关文章

随机推荐

  • SQL:数据去重的三种方法

    1 使用distinct去重 distinct用来查询不重复记录的条数 xff0c 用count distinct id 来返回不重复字段的条数 用法注意 xff1a distinct 查询字段 xff0c 必须放在要查询字段的开头 xff
  • Word页面中四个直角

    文章目录 1 四个直角1 xff09 代表页边距2 xff09 页边距的设置3 xff09 打开或关闭 裁剪标记 2 裁剪标记 与图片1 xff09 插入图片超过这个角能打印显示出来吗 xff1f 3 裁剪标记 与表格 1 四个直角 1 x
  • windows搭建ftp及原理(小白向)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 环境一 实验步骤1 1安装ftp 二 ftp实验引发的思考1 简单阐述ftp的原理2 ftp建立的流程 总结 环境 windwo
  • Win10系统自动更新失败(错误代码0x800f0922)

    笔者最近遇到了Win10系统自动更新失败的问题 xff0c 错误代码0x800f0922 每次更新下载安装完 xff0c 重启电脑的时候就会提示 xff1a 我们无法完成更新 正在撤销更改 在设置 Windows更新中有 xff1a 202
  • Linux yum安装redis

    1 安装redis数据库 yum install redis 2 下载fedora的epel仓库 yum install epel release 3 启动redis服务 systemctl start redis 4 查看redis状态
  • Centos 开启X11 Forwarding,实现无桌面环境运行GUI软件

    文章目录 修改SSH配置文件sshd config安装 X11 Forwarding 相关软件重启 sshd 服务 xff0c 并重新SSH连接验证 我们新安装Centos时可能会选择最小安装 xff0c 不安装桌面环境 xff0c 但是后
  • Python pyttsx3|文本朗读(各种语言)

    Python文字转语音 程序员 xff0c 在其他人眼中往往都是高冷的存在 xff0c 在他们的眼中能用代码解决的问题绝对不考虑其他的方法 xff0c 本文让我们用Python来提升一下高冷的档次 xff0c 让我们用代码来 说话 安装py
  • Spring Security 出现 'login.html?error' is not a valid redirect URL 异常

    原因是这个URL地址要以 打头 例如 xff1a 报错的代码 xff1a http span class token punctuation span span class token function formLogin span spa
  • 5. Python3的基本类型(元组)

    Python3的基本类型 xff08 元组 xff09 1 Python 的元组与列表相似 xff0c 不同之处 xff1a 元组不能修改 xff0c 元组使用小括号 xff0c 列表使用方括号 2 元组的创建 xff1a 只需要在括号中添
  • group by内部排序

    规则 xff1a 第一 xff0c 凡是在group by后面出现的字段 xff0c 必须同时在select后面出现 xff1b 第二 xff0c 凡是在select后面出现的 同时未在聚合函数中出现的字段 xff0c 必须同时出现在gro
  • 李宏毅机器学习(四)Spatial Transformer Layer

    学习内容 架构 xff1b 目的就是克服CNN的旋转和缩放不变性的缺点的 xff01 前情提要 CNN is not invariant to scaling and rotation xff1b CNN对缩放和旋转不是不变的 xff1b
  • python修改pip安装镜像源

    pip 默认的安装源安装真的很慢 xff0c 所以我们可以换成国内的一些优质的安装源 通用临时方法 pip install package name i https pypi tuna tsinghua edu cn simple 永久修改
  • 深入理解 Java 线程池的实现原理

    文章目录 1 线程状态2 线程池2 1 线程池的作用2 2 线程池的实现2 2 1 线程池内部状态 1 线程状态 既然要说线程 xff0c 我们就先来了解一下线程的几种状态 xff1a span class token keyword pu
  • windows server安装域控及原理(小白向)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 安装环境一 安装域控二 说明一下遗留的问题总结 这个是一系列的博客文章 xff0c 域控只是开始 安装环境 windwos任意s
  • 详述 Redis 选择单线程模型的原因以及 I/O 多路复用

    文章目录 Redis 选择单线程模型的原因概述设计单线程模型可维护性并发处理性能瓶颈 引入多线程删除操作 总结 Redis 和 IO 多路复用几种 I O 模型Blocking I OI O 多路复用 Reactor 设计模式I O 多路复
  • 新一代垃圾回收器 ZGC 的探索与实践

    文章目录 GC之痛CMS 与 G1 停顿时间瓶颈标记阶段停顿分析清理阶段停顿分析复制阶段停顿分析 ZGC原理全并发的 ZGCZGC 关键技术ZGC 并发处理演示 ZGC 调优实践调优基础知识理解 ZGC 重要配置参数理解 ZGC 触发时机理
  • 详述 Spring 中 Bean 的作用域、事务的隔离级别以及传播行为

    文章目录 Bean 作用域XML 声明singletonprototyperequestsessionglobalSession 注解声明 事务隔离级别事务传播行为 Bean 作用域 Spring IOC 容器创建一个 Bean 实例时 x
  • 饿了么交易系统 5 年演化史

    作者介绍 xff1a 杨凡 xff0c 花名挽晴 xff0c 饿了么高级架构师 xff0c 2014 年加入饿了么 xff0c 2018 年随饿了么被阿里巴巴收购一同加入阿里巴巴 xff0c 4 年团队管理经验 xff0c 4 年主要从事饿
  • 带你了解「美团、百度和滴滴」的分布式 ID 生成系统

    文章目录 美团背景常见方法介绍UUID类snowflake方案数据库生成 Leaf 方案实现Leaf segment 数据库方案双 buffer 优化Leaf 高可用容灾 Leaf snowflake 方案弱依赖 ZooKeeper解决时钟
  • Spring Cloud 优雅下线以及灰度发布

    文章目录 前言优雅下线常见的下线方式优雅的下线方式 灰度发布蓝绿部署滚动部署金丝雀部署 前言 在生产环境中 xff0c 如何保证在服务升级的时候 xff0c 不影响用户的体验 xff0c 这个是一个非常重要的问题 如果在我们升级服务的时候