SpringCloud 应用在 Kubernetes 上的最佳实践 — 线上发布(优雅上下线)

前言

上篇我们讲的是发布回滚过程,尤其是在 Kubernetes 的回滚过程中,原生有提供 Rollout 到上一个版本的能力,能保证我们在发布过程中遇到问题时快速回退的能力。然而在每一次上线的过程中,我们最难处理的就是正在运行中的流量,如何做到流量的无损上/下线,是一个系统能保证 SLA 的关键。

介绍

什么是优雅上线?就如下面这个房子一样,未建好的房子,人住进去会有危险,房子应该建好,装修好,人才能住进去。

1.jpeg

那么如何做到优雅上线,我们先来看一个WEB应用的加载过程,就像上面造房子一样,是个漫长的过程:

QzpcVXNlcnNcd2Itd3h5NTg0MzIzXEFwcERhdGFcUm9hbWluZ1xEaW5nVGFsa1w2ODY4MzMyNzFfdjJcSW1hZ2VGaWxlc1wxNTk3MTUwMzc4Nzc0X0RDQUVBQThELUJERjMtNDcyMi1BNUVGLThGMTIxNUE0NUI1Mi5wbmc=.png

应用的加载是漫长的,在加载过程,服务是不可预期的;如过早的打开Socket监听,则客户端可能感受到漫长的等待;如果数据库、消息队列、REDIS客户端未完成初始化,则服务可能因缺少关键的底层服务而异常。
所以在应用准备完成后,才接入服务,即做到优雅上线。当然应用上线后,也可能因如数据库断连等情况引起服务不可用;或是准备完成了,但在上线前又如发生数据库断连,导致服务异常。为了简化问题,后面两种情况作为一个应用自愈的问题来看待。
什么是优雅下线?与建房子相反就像下面的危房一样,人住在里面很危险,人应该先从房子出来,然后推掉房子。
3.jpeg

那么如何做到优雅下线,我们先来看一个WEB应用的停止过程:
QzpcVXNlcnNcd2Itd3h5NTg0MzIzXEFwcERhdGFcUm9hbWluZ1xEaW5nVGFsa1w2ODY4MzMyNzFfdjJcSW1hZ2VGaWxlc1wxNTk3MTQ5MjA0MDM2XzNCQjdGQ0FCLUI1OUQtNDY4YS1CRjI3LTdDQ0I1MDU0NTMxRi5wbmc=.png

所以关闭服务接入(转移服务接入),完成正在处理的服务,清理自身占用的资源后退出即做到优雅下线。

如何实现优雅下线

从上面介绍看,似乎不难,但事实上,很少系统真正实现了优雅上下线。因为软件本身由无数各种各样相互依赖的结构组成,每个结构都使用一些资源,污染一些资源;通常在设计之初优雅上下线也不被作为优先考虑的需求,所以对于下线的过程,通常都没被充分考虑,在设计上通常要求:

  • 结构(组件)应形成层次关系。
  • 用户线程需能收到停止信号并响应退出;否则使用daemon线程。
  • 结构应按依赖关系自下向上构建:就像建房子一样,自内向外构建而成。
  • 结构应按依赖关系自上向下销毁:就像拆房子一样,自外向内拆解。

优雅下线实现路径

大致分为一个完整的过程,需要经历一下四个关键的节点,如下图;
5.png

  • 接收信号:停止信号可能从进程内部触发(比如 Crash 场景),如果自退出的话基本上无法保证优雅下线;所以能保证优雅下线的前提就是需要正确处理来自进程外部的信号。
  • 停止流量接收:由于在停止之前,我们会有一些正在处理的请求,贸然退出会对这些请求产生损耗。但是在这段时间之内我们绝不能再接收新的业务请求,如果这是一个后台任务型(消息消费型或任务调度型)的程序,也要停止接收新的消息和任务。对于一个普通的 WEB 场景,这一块不同的场景实现的方式也会不一样,下面的 Srping Cloud 应用的下线流程会详细讲解。
  • 销毁资源:常见的是一些系统资源,也包括一些缓存、锁的清理、同时也包括线程池、关闭阻塞中的的IO操作,等到我们这些服务器资源销毁之后,就可以通知主线程退出。

Spring Cloud应用

一个Spring boot应用通常由应用本身加一系列的Starter组成,对于Spring boot体系,需要了解如下核心概念:

  • Starter:提供一系列的模块,由Spring boot核心通过auto-configuration机制加载。
  • Bean:一切皆Bean,starter模块的加载产生各种Bean。
  • Context:Bean的容器,容器拥有生命周期,Bean需要感知生命周期事件。
  • LifeCycle:生命周期管理接口。
  • ApplicationEvent:模块之间,模块与容器之间,通过发送或监听事件来达到互相通讯的目的。
    所以对于应用上下线这个主题,我们应尽可能利用其丰富的原生事件机制,Spring Cloud 中内置的 Starter 机制针对整个生命周期管理的过程有了很好的封装。

Spring Cloud应用的优雅上线

Spring Cloud 启动过程触发回调及事件如下,详细介绍见application-events-and-listeners,简单罗列如下:
QzpcVXNlcnNcd2Itd3h5NTg0MzIzXEFwcERhdGFcUm9hbWluZ1xEaW5nVGFsa1w2ODY4MzMyNzFfdjJcSW1hZ2VGaWxlc1wxNTk3MTQ5MjM4MzUwX0I3RURBRDIzLTc0NEYtNDljZi1BNjQ5LUVFNjQ4NkE3N0Y1Mi5wbmc=.png

Spring自身及其组件大量基于这些事件构建,如响应WebServerInitializedEvent事件向服务注册中心注册服务,对于应用一般可利用:

  • InitializingBean or @PostConstruct:在Bean装配完后,被回调,如完成数据源初始化连接。
  • ApplicationReadyEvent、ApplicationRunner、CommandLineRunner:如开始监听消息队列,处理消息;注册到SLB等;先通过配置禁用服务的自动注册,在这里做手动服务注册。

Spring Cloud应用的优雅下线

Spring Cloud 本身可以作为一个应用单独存在,也可以是依附在一个微服务集群中,同时还能作为反向代理架构中的一个网关。不同的场景,需要用到的方法也不一样,我们就常用的三种场景针对性的加以说明。

场景一:直接访问WEB服务

6.png

客户端直接访问WEB应用,在这个用例下,优雅下线需要做的事情有:

  • 正在处理的请求完成处理
  • 应用自身完成的安全下线并正常退出
  • 客户端感知到连接异常

Spring-boot从2.3开始内置了WEB应用优雅下线的能力,需配置如下,具体介绍参见graceful-shutdown

server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=20s

其实现方式:

  • 首先关闭socket监听,等待正在处理的所有请求完成:具体可见WebServerGracefulShutdownLifecycle,通过getPhase返回最大值,达到早于WEB容器关闭执行的目的,
  • 然后触发WEB容器关闭:具体可见WebServerStartStopLifecycle

但其实,对于未被WEB容器完全接收的请求,客户端仍会收到连接被重置的异常,只是这个时间窗口极小。该需求从提出到实现的时间跨度较长,感兴趣的可参见github上的讨论。

场景二:经由反向代理的服务优雅下线

7.jpeg

因为实例前面还有反向代理,相比上个场景,需要新增“反向代理下线”这个处理流程。即若应用已经下线,但反向代理未摘除该应用实例时客户端将感知到失败。一般采取的策略有:

  • 反向代理支持失败转移到其它应用实例
  • 在关闭应用前,如将健康探测接口返回不健康以及等待足够的超时,让反向代理感知并摘除实例的路由信息。

对于仍在使用2.3以前版本的Spring Cloud应用,可参见一个方案,实现方式:

  • 使用自身的shutdownHook替换Spring的shutdownHook
  • 先改变health状态,等待一段时间,让反向代理感知并摘除实例的路由信息

场景三:在微服务集群中下线单个服务

8.jpeg

在优雅关闭Spring Cloud应用自身之前,我们除了完成场景一之中的目标之外,还需要将自身节点从注册中心中下线。目前在Spring Cloud中针对注册中心下线的场景暂未提供开箱即用的方法,下面介绍两种可能的实现方案:

  • 方案1:先通过脚本、或通过监听ContextClosedEvent反注册服务摘除流量;等待足够时间,如使用ribbon负载均衡器,需要长于配置的刷新时间;对于基于HTTP的服务,若Spring Cloud版本小于2.3,则时间需加上预期的请求处理时间。
  • 方案2:客户端支持连接感知重试,如重试,实现方案可参考Spring-retry,针对连接异常RemoteConnectFailureException做重试。
    针对 Eureka 中的场景,有一个很好的参考的例子,请参见:https://home1-oss.github.io/home1-oss-gitbook/release/docs/oss-eureka/GRACEFUL_SHUTDOWN.html

Kubernetes 下的机制

Kubernetes 中针对应用的的管控提供了丰富的手段,正常的情况他提供了应用生命周期中的灵活的扩展点,同时也支持自己扩展他的 Operator 自定义上下线的流程。
9.jpeg

抛开实现成本,以下线的情况来说,一个 Kubernetes 应用实例下线之前,管控程序会向 POD 发送一个 SIGTERM 的信号,应用响应时除了额外响应这一个信号之外,还能触发一段自定义的 PreStop 的挂在脚本,代码样例如下:

yaml
lifecycle:                   preStop:                   exec:                    command:               - sh- -c- "sleep 5"

上面的例子一点特殊说明:因服务控制面刷新与POD收到SIGTERM同时发生,所以这里通过sleep 5让服务控制面先完成刷新,应用进程再响应SIGTERM信号。

Spring Cloud 与 Kubernetes 的结合

Kubernetes 会根据健康检查的情况来更新服务(Service)列表,其中如果 Liveness 失败,则会触发容器重建,这是一个相对很重的操作;若 Readiness 失败,则 Kubenetes 则默认不会将路由服务流量到相应的容器;基于这一基理,Spring Cloud 2.3开始,也做了原生的的支持,具体参见 liveness-and-readiness-probes-with-Spring-boot,这些健康检查端点可对接kubnetes相应的probe:

  • /actuator/health/liveness
  • /actuator/health/readiness

同时,Spring Boot 内置了相应的 API、事件、Health Check 监控,部分代码/配置片段如下:

java
// Available as a component in the application context
ApplicationAvailability availability;LivenessState livenessState = availabilityProvider.getLivenessState();
ReadinessState readinessState = availabilityProvider.getReadinessState();
....
// 对于应用,也可以通过API,发布相应的事件,来改变应用的状态
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);// 同时,应用监控也可影响这健康状态,将监控与健康关联,在K8S体系下,可以实现如离群摘除,应用自愈的能力
// application.properties
management.endpoint.health.group.liveness.include=livenessProbe,cacheCheck

回到 Spring Cloud 应用 在微服务集群中下线单个服务 的章节中,我们的应用如果跑在 Kuberntes 中,如果我们使用了原生的 Kubernetes 机制去管理应用生命周期的话,只需要发布一个应用事件(LivenessState.BROKEN)即可实现优雅下线的能力。

 

后续

这一章节之后,和发布相关的内容都已经更新完毕,下一章节我们要开始高可用部分的能力,高可用也是系统保障 SLA 的关键部分,简单的理解是流量洪峰到来如何保证系统不会受到影响?当然我们还有一部分要达成的是洪峰退去之后资源是否存在浪费?敬请期待 ...

 

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

菜鸟+Hologres=智能物流

作者:阿里巴巴菜鸟物流团队(弃疾,孝江,姜继忠) 一、业务背景 菜鸟智能物流分析引擎是基于搜索架构建设的物流查询平台,日均处理包裹事件几十亿,承载了菜鸟物流数据的大部分处理任务。 智能物流…

这个宝藏工具,会给你一种黑客般的感觉

明天要交作业了,吴检正在宿舍熬夜爆肝拼命敲代码,劈里啪啦的键盘声和咔咔的鼠标声格外嘈杂,室友陈琛瞥了一眼,背过身,沉沉睡去,留下他一人在深夜无尽的黑暗中,断断续续却又没有尽头的咔咔声中凌…

全民加速节:解读CDN的应用场景与产品价值

8月12日,全民加速节第二次直播中,阿里云CDN产品专家寒丰进行了《阿里云CDN产品解读》的主题分享,从CDN的趋势、变迁、价值三个方面来阐述思考,并对阿里云CDN产品的业务架构和价值进行解读。 当下,互联网的应用服务已经…

抖音实战~评论数量同步更新

文章目录一、快速入门1. 子组件2. 父组件3. 子组件回调父页面4. 父组件接收回调5. 组件调用流程二、抖音评论数量2.1. 流程图2.2. 流程简述2.3. 流程图效果图鉴赏一、快速入门 1. 子组件 <view clickchildBackHome></view>2. 父组件 父组件说明&#xff1a; bac…

实时化或成必然趋势?新一代 Serverless 实时计算引擎

作者&#xff1a;高旸&#xff08;吾与&#xff09;&#xff0c;阿里巴巴高级产品专家 本文由阿里巴巴高级产品专家高旸&#xff08;吾与&#xff09;分享&#xff0c;主要介绍新一代Serverless实时计算引擎的产品特性及核心功能。 一&#xff0e;实时计算 Flink 版 – 产品定…

抢先看!Kubernetes v1.21 新特性一览

作者 | 倪朋飞来源 | 漫谈云原生头图 | 下载于视觉中国Kubernetes v1.21 下个月就要发布了&#xff08;v1.21.0 将于 4 月 8 日发布&#xff09;&#xff0c;本文梳理该版本带来的新特性&#xff0c;以便你为下个月的升级做好准备。PodSecurityPolicy 弃用PodSecurityPolicy&am…

阿里云ARMS助力「叫叫阅读」解锁系统定位分析技能包

叫叫阅读系列是成都书声科技有限公司&#xff08;铁皮人&#xff09;旗下的教育Apps。 主要针对3-12岁孩子&#xff0c;以儿童身心发展规律为依据&#xff0c;秉承叶圣陶先生的语文教育论&#xff0c;多读书&#xff0c;读好书&#xff0c;勤思考。由小学语文老师、幼小衔接专家…

开放下载!《AliOS Things快速开发指南》

简介&#xff1a; 《AliOS Things快速开发指南》手把手教你从环境准备到线上、线下开发调试&#xff0c;更有两大典型场景实践等你参与。你的物联网开发从这里开始&#xff01;快来get新技能吧~ AliOS Things致力于搭建云端一体化IoT基础设施&#xff0c;具备极致性能、极简开…

低代码,填补业务技术鸿沟 or 紧贴业务的开发时代?

作者 | 宋慧 出品 | CSDN云计算 头图 | 付费下载于视觉中国 低代码在技术界一波又一波的讨论中&#xff0c;仍在不断发展中。3 月 30 日&#xff0c;国内企业数字化服务商奥哲举行品牌全新升级暨新品发布&#xff0c;并推出面向业务人员的新产品&#xff1a;数字化管理工具“奥…

我在阿里写代码学会的六件事

简介&#xff1a; 从团队的角度来看&#xff0c;写好代码是一件非常有必要的事情。如何写出干净优雅的代码是个很困难的课题&#xff0c;我没有找到万能的 solution&#xff0c;更多的是一些 trade off&#xff0c;可以稍微讨论一下。 写了多年的代码&#xff0c;始终觉得如何写…

FLOWABLE 流程中的自动跳过

文章目录1. 背景2. 流程3. 实施方案1. 背景 在实际场景中&#xff0c;我们往往会有这样的需求&#xff0c;当流程到达某一个节点的时候&#xff0c;当某角色或岗位不存在时直接跳过当前节点&#xff0c;到下一个节点&#xff08;我们让其自动的跳过去&#xff0c;不做任何操作…

减少运维工作量,如何通过 ROS 轻松实现资源编排新方式

简介&#xff1a; 以“基础设施即代码”的理念代替“重复劳动”。 在日常工作中&#xff0c;我们一定遇到过需要快速构建系统的工作情形&#xff1a; 作为资源管理人员&#xff0c;需要接收一定数量以及配置的资源申请&#xff0c;这些申请要求网络、存储设备按需到位&#xf…

开放下载!《无需从0开发 平头哥教你1天上手蓝牙Mesh应用解决方案》

当你疲惫了一天&#xff0c;回到家里&#xff0c;点点手机灯就亮了&#xff0c;再唤醒天猫精灵放首歌&#xff0c;这样智能的家&#xff0c;恐怕这是很多人梦寐以求的吧。而蓝牙 MESH 智能灯&#xff0c;是智能家居系统中最基础的设施。蓝牙 MESH 智能灯是如何实现轻松、高效地…

2020 年微服务项目活跃度报告

简介&#xff1a; 2020 年 8 月 18 日&#xff0c;首届云原生微服务大会于线上召开&#xff0c;会议首日&#xff0c;阿里云资深技术专家、CNCF TOC 李响 Keynote 演讲中正式发布了《 2020 年微服务领域开源数字化报告》。 导读&#xff1a;2020 年 8 月 18 日&#xff0c;首届…

又一低代码平台火了!15 分钟小白轻松开发在线课堂,人人都是开发者时代来了?

据艾瑞咨询统计&#xff0c;2020 年中国在线教育行业市场规模 2573 亿元&#xff0c;过去 4 年的复合增长率达 34.5%。如今在线教育行业如火如荼&#xff0c;亟待一款好的在线教育平台。 此时&#xff0c;不少开发者和教育机构遇到新的难题&#xff1a;如果使用标准化 SaaS 平…

阿里巴巴大数据实践—实时技术

来源&#xff1a;数智化转型俱乐部 数据价值是具有时效性的&#xff0c;在一条数据产生的时候&#xff0c;如果不能及时处理并在业务系统中使用&#xff0c;就不能让数据保持最高的“新鲜度”和价值最大化。 相对于离线批处理技术&#xff0c;流式实时处理技术作为一个非常重…

全民加速节:全站加速在互联网媒体应用上的最佳实践

8月19日&#xff0c;全民加速节第三场直播中&#xff0c;阿里云CDN解决方案架构师拓州进行了《全站加速在媒体服务行业的实践》主题分享&#xff0c;针对互联网媒体服务行业中的特征和痛点&#xff0c;介绍阿里云全站加速产品的应用实践。 互联网媒体服务的特征 互联网媒体服…

云原生全景图之六 | 托管 Kubernetes 和 PaaS 解决什么问题

作者 | Catherine Paganini、Jason Morgan来源 | K8sMeetup头图 | 下载于视觉中国在本系列之前的文章中&#xff0c;我们讨论了 CNCF 云原生全景图的各层&#xff1a;供应层、运行时层、编排管理层以及应用定义和开发层。本文我们将聚焦在平台层。正如我们在本系列文章中看到的…

报告:5G 网络切片可能会给不法分子留下漏洞!

责编 | 寇雪芹头图 | 下载于视觉中国据爱尔兰安全公司 AdaptiveMobile Security 的一份报告显示&#xff0c;由于缺乏传输层与应用层之间的映射关系&#xff0c;因此结合了传统技术的 5G 网络可能更容易受到威胁。网络切片对于实现5G的许多功能至关重要。网络切片&#xff08;N…

独家下载!小程序Serverless云上开发一站到底

阿里云小程序Serverless 提供包括云函数、数据存储、文件存储等一整套后端服务。开发者通过API 方式即可获取云函数、数据存储、文件存储、音视频、图像处理等服务&#xff0c;不需要关心服务器或底层运维设施&#xff0c;可以更专注于代码和业务本身。 《小程序Serverless 云…