Serverless 架构下的服务优雅下线实践

本文涉及的产品
简介: 应用发布、服务升级一直是一个让开发和运维同学既兴奋又担心的事情。兴奋的是有新功能上线,自己的产品可以对用户提供更多的能力和价值;担心的是上线的过程会不会出现意外情况影响业务的稳定性。确实,在应用发布和服务升级时,线上问题出现的可能性更高,本文我们将结合 Serverless 应用引擎(以下简称 SAE)就 Serverless 架构下,讨论如何保障上线过程中服务的优雅下线。

应用发布、服务升级一直是一个让开发和运维同学既兴奋又担心的事情。

兴奋的是有新功能上线,自己的产品可以对用户提供更多的能力和价值;担心的是上线的过程会不会出现意外情况影响业务的稳定性。确实,在应用发布和服务升级时,线上问题出现的可能性更高,本文我们将结合 Serverless 应用引擎(以下简称 SAE)就 Serverless 架构下,讨论如何保障上线过程中服务的优雅下线。

在平时的发布过程中,我们是否遇到过以下问题:

  • 发布过程中,出现正在执行的请求被中断?
  • 下游服务节点已经下线,上游依然继续调用已经下线的节点导致请求报错,进而导致业务异常?
  • 发布过程造成数据不一致,需要对脏数据进行修复。

有时候,我们把发版安排在凌晨两三点,赶在业务流量比较小的时候,心惊胆颤、睡眠不足、苦不可言。那如何解决上面的问题,如何保证应用发布过程稳定、高效,保证业务无损呢?首先,我们来梳理下造成这些问题的原因。

场景分析

1.png

这个图描述了我们使用微服务架构开发应用的一个常见的场景,先看下这个场景的服务调用关系:

  • 服务 B、C 把服务注册到服务注册中心,服务 A、B 从注册中心发现依赖的服务。
  • 业务流量从负载均衡路由到服务 A,在 SLB 上配置服务 A 实例的健康检查,当服务 A 有实例停机的时候,相应的实例从 SLB 摘掉;服务 A 调用服务 B,服务B再调用服务C。

从图中,可以看到有两类流量,南北向流量(即通过 SLB 转发到后端服务器的业务流量,如业务流量->SLB->A的调用链路)和东西向流量(借助于服务注册中心服务发现调用的流量,如服务A->服务B的调用链路)

针对这两类流量我们分别进行分析。先来分析下在这种架构下南北向流量存在的问题,当服务 A 发布的时候,服务A1 实例停机后,SLB 根据健康检查探测到实例 A1 下线,然后把实例从 SLB 摘掉,实例 A1 依赖 SLB 的健康检查从 SLB 上摘掉,一般需要几秒到十几秒的时间,在这个过程中,如果 SLB 有持续的流量打入,就会造成一些请求继续路由到实例 A1,导致请求失败。

那如何保证经过SLB的业务流量不报错?我们看下 SAE 是如何做到的。

南北向流量优雅下线方案

2.png

上面提到过,请求失败的原因在于后端服务实例先停止掉,然后才从 SLB 摘掉,那我们是不是可以先从 SLB 摘掉服务实例,然后在对实例进行升级呢?

按照这个思路,SAE 基于 K8s Service 的能力给出了一种方案,当用户在通过 SAE 为应用绑定 SLB 时,SAE 会在集群中创建一个 Service 资源,并把应用的实例和 Service 关联,CCM 组件会负责 SLB 的购买、SLB 虚拟服务器组的创建,并且把应用实例关联的 ENI 网卡添加到虚拟服务器组中,从而用户可以通过 SLB 来访问应用实例;当应用发布时,CCM 组件会先把实例对应的 ENI 从虚拟服务器组中摘除,然后再对实例进行升级,从而保证了流量不丢失。

东西向流量优雅下线方案

在讨论完南北向流量的解决方案后,我们再看下东西向流量, 传统的发布流程中,服务提供者停止再启动,服务消费者感知到服务提供者节点停止的流程如下:

3.png

  • 服务发布前,消费者根据负载均衡规则调用服务提供者,业务正常。
  • 服务提供者 B 需要发布新版本,先对其中的一个节点进行操作,首先是停止 Java 进程。
  • 服务停止过程,又分为主动注销和被动注销,主动注销是准实时的,被动注销的时间由不同的注册中心决定,最差的情况会需要 1 分钟。
  • 如果应用是正常停止,Spring Cloud 和 Dubbo 框架的 Shutdown Hook 能正常被执行,这一步的耗时可以忽略不计。
  • 如果应用是非正常停止,比如直接使用 kill -9 停止,或者 Docker 镜像构建的时候 Java 应用不是 1 号进程且没有把 kill 信号传递给应用。那么服务提供者不会主动去注销服务节点,而是在超过一段时间后由于心跳超时而被动地被注册中心摘除。
  • 服务注册中心通知消费者,其中的一个服务提供者节点已下线。包含推送和轮询两种方式,推送可以认为是准实时的,轮询的耗时由服务消费者轮询间隔决定,最差的情况下需要 1 分钟。
  • 服务消费者刷新服务列表,感知到服务提供者已经下线了一个节点,这一步对于 Dubbo 框架来说不存在,但是 Spring Cloud 的负载均衡组件 Ribbon 默认的刷新时间是 30 秒 ,最差情况下需要耗时 30 秒。
  • 服务消费者不再调用已经下线的节点。

从第 2 步到第 6 步的过程中,Eureka 在最差的情况下需要耗时 2 分钟,Nacos 在最差的情况下需要耗时 50 秒。在这段时间内,请求都有可能出现问题,所以发布时会出现各种报错。

经过上面的分析,我们看,在传统发布流程中,客户端有一个服务调用报错期,原因就是客户端没有及时感知到服务端下线的实例造成的,这种情况主要是因为服务提供者借助注册中心通知消费者来更新服务提供者列表造成的,那能不能绕过注册中心,服务提供者直接通知服务消费者呢?答案是肯定的,SAE 主要做了两件事情。
4.png

  • 服务提供者应用在发布前后主动向注册中心注销应用,并将应用标记为已下线的状态;将原来的停止进程阶段 注销服务变成了 prestop 阶段注销服务。
  • 在接收到服务消费者请求时,首先会正常处理本次调用,并通知服务消费者此节点已下线,服务消费者会立即从调用列表删除此节点;在这之后,服务消费者不再调用已经下线的节点。这是将原来的依赖于 注册中心推送,变成了服务提供者直接通知消费者从调用列表中摘除自己。

通过上面这个方案,就使得下线感知的时间大大减短,从原来的分钟级别做到准实时,确保您的应用在下线时能做到业务无损。

分批发布和灰度发布

上面介绍的是 SAE 在处理优雅下线方面的一些能力,在应用发布的过程中,只有实例的优雅下线是不够的,需要有一套配套的发布策略,保证我们新业务是可用的,SAE 提供了分批发布和灰度发布的能力,可以使得应用的发布过程更加省心省力;

我们先介绍下灰度发布,某应用包含10个应用实例,每个应用实例的部署版本为Ver.1版本,现需将每个应用实例升级为Ver.2版本。
5.png

从图中可以看出,在发布的过程中先灰度2台实例,在确认业务正常后,再分批发布剩余的实例,发布的过程中始终有实例处于运行状态,实例升级过程中依照上面的方案,每个实例都有优雅下线的过程,这就保证了业务无损。

再来看下分批发布,分批发布支持手动、自动分批;还是上面的10个应用实例,假设将所有应用实例分3批进行部署,根据分批发布策略,该发布流程如图所示,就不再具体介绍了。
6.png

如果您想体验 Serverless 架构下在微服务应用的优雅下线、分批发布和灰度发布方面的能力,欢迎您登陆 SAE 的 控制台 >>

【更多精彩】

1.中间件爆款一折起,还有阿里巴巴十年最佳实践深度解密,点击马上了解https://www.aliyun.com/activity/daily/commercial?spm=5176.20960838.0.0.6a54305etoEn4D

2.【填问卷领淘公仔】点击马上填写问卷:
https://survey.aliyun.com/apps/zhiliao/YmW95Gk8bU

【加入行业实战交流钉钉群】

阿里云专门成立了“互联网架构升级实战课”钉钉群,每周邀请一位阿里云专家在群内进行行业最佳实践直播,每天分享行业前沿干货,钉钉扫码马上加入。
image.png

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
4天前
|
运维 监控 Devops
深入理解微服务架构:从理论到实践
随着数字化转型的加速,微服务架构已成为现代软件开发的重要趋势。本文将通过数据导向和科学严谨的分析方法,探讨微服务架构的核心概念、优势与挑战,并结合逻辑严密的案例研究,揭示如何在实际项目中有效实施微服务。我们将引用权威研究和统计数据,深入解读微服务对企业技术栈的影响,同时提供一套完整的微服务实施策略,旨在帮助读者构建更加灵活、可维护的软件系统。
|
4天前
|
设计模式 安全 持续交付
探索微服务架构下的后端开发实践
在现代软件开发领域,微服务架构已成为一种流行的设计模式,它通过将应用程序分解为一组小的服务来促进敏捷开发和可扩展性。本文深入探讨了微服务架构的核心概念、技术选型、数据一致性挑战以及安全性考虑,旨在为后端开发人员提供一份全面的微服务开发指南。文章结合最新的研究成果和业界最佳实践,分析了微服务架构的优势和面临的挑战,并提出了相应的解决方案。读者将了解到如何在实际项目中应用微服务原则,以及如何克服实施过程中的技术和组织障碍。
|
5天前
|
存储 设计模式 监控
后端开发中的微服务架构实践与挑战
在数字化时代背景下,微服务架构作为现代软件工程的典范,被广泛应用于后端开发领域。本文将深入探讨微服务架构的核心概念、实施策略及其面临的主要挑战,同时提供一系列针对性的解决方案和最佳实践。通过引用最新的研究成果和行业案例,文章旨在为后端开发者提供一个全面的微服务架构指南,帮助他们在构建和维护复杂系统时做出明智的决策。
15 1
|
3天前
|
中间件 BI 测试技术
【实践篇】领域驱动设计:DDD工程参考架构
领域驱动设计(DDD)参考架构旨在为团队提供DDD实践的起点,强调业务与技术的分离,考虑多种架构风格如分层、六边形等。它包括多限界上下文结构,每个上下文内有应用层(不含领域逻辑)、领域层(含领域模型和事件)和网关层。接入层负责外部请求的处理,业务层协调不同上下文。组件包括Start(启动)、Common(通用)、API、Facade、Application Service、External API、Query、Domain和Gateway,各组件有明确的职责和依赖关系,如Gateway处理技术细节并作为系统与外部的接口。架构设计是多因素权衡,适应实际工程需求。
|
5天前
|
Cloud Native 持续交付 云计算
云原生架构的演进与实践
随着云计算技术的不断成熟,云原生架构逐渐成为企业数字化转型的核心驱动力。本文将深入探讨云原生架构的发展历程、关键技术组件以及在实际应用中的优化策略。通过分析最新的行业数据和案例研究,揭示云原生技术如何推动业务敏捷性、提升系统可靠性和降低运营成本。
|
5天前
|
消息中间件 监控 API
后端开发中的微服务架构实践与挑战
在现代软件开发中,微服务架构因其灵活性和可扩展性而受到广泛推崇。本文将深入探讨微服务的核心概念、实施步骤以及面临的技术挑战,同时结合最新的研究数据和行业案例,分析微服务在实际应用中的表现和优化策略,为后端开发人员提供一份实用的指南。
8 0
|
5天前
|
边缘计算 Cloud Native 持续交付
云原生架构的演进与实践
本文旨在深入探讨云原生架构的发展脉络,从其起源到现代应用的实践。通过分析云原生技术的演变过程和当前企业中的应用案例,本文揭示了云原生架构如何促进企业的数字化转型。文章将详细讨论容器化、微服务、持续集成/持续部署(CI/CD)等关键技术,并通过实际案例展示这些技术如何解决现实世界的问题。此外,文章还将探讨云原生技术面临的挑战和未来的发展趋势,为读者提供全面而深入的云原生架构视角。
12 0
|
6天前
|
消息中间件 监控 Java
Java中的可扩展微服务架构设计实践
Java中的可扩展微服务架构设计实践
|
6天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【7月更文挑战第1天】Spring Cloud是Java微服务治理明星框架,整合Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心),提供完整服务治理解决方案。通过Eureka实现服务注册与发现,Ribbon进行客户端负载均衡,Hystrix确保服务容错,Config Server集中管理配置,Zuul作为API网关简化系统复杂性。理解和使用Spring Cloud是现代Java开发者的关键技能。
18 0
|
6天前
|
运维 Cloud Native Devops
云原生架构的演进与实践:面向未来的企业技术战略
在数字化转型的浪潮中,云原生架构已成为推动企业技术创新和业务敏捷性的核心力量。本文旨在深入探讨云原生架构的发展历程、关键技术组件以及在实际应用中的效益与挑战。通过分析来自全球不同行业的实证数据和案例研究,文章揭示云原生技术如何助力企业实现资源的高效利用、应用的快速迭代和系统的弹性扩展。同时,结合最新的研究成果和行业报告,为读者提供一套系统化的云原生采纳指南和战略规划建议,以期帮助企业构建面向未来的技术体系,并在激烈的市场竞争中保持领先地位。
25 0

热门文章

最新文章

相关产品

  • 函数计算