15 分钟实现企业级应用无损上下线

简介:很多用户量大并发度高的应用系统为了避免发布过程中的流量有损,一般选择在流量较小的半夜发布,虽然这样做有效果,但不可控导致背后的研发运维成本对企业来说是一笔不小的负担。基于此,阿里云微服务引擎 MSE 在应用发布过程中,通过应用下线时进行自适应等待+主动通知,应用上线时就绪检查与微服务生命周期对齐+服务预热等技术手段所提供的微服务应用无损上下线功能,能有效帮助企业规避线上发布所出现的流量资损。

很多用户量大并发度高的应用系统为了避免发布过程中的流量有损,一般选择在流量较小的半夜发布,虽然这样做有效果,但不可控导致背后的研发运维成本对企业来说是一笔不小的负担。基于此,阿里云微服务引擎 MSE 在应用发布过程中,通过应用下线时进行自适应等待+主动通知,应用上线时就绪检查与微服务生命周期对齐+服务预热等技术手段所提供的微服务应用无损上下线功能,能有效帮助企业规避线上发布所出现的流量资损。

无损上下线功能设计

常见的流量有损现象出现的原因包括但不限于以下几种:

  • 服务无法及时下线:服务消费者感知注册中心服务列表存在延时,导致应用下线后在一段时间内服务消费者仍然调用已下线应用造成请求报错。
  • 初始化慢:应用刚启动接收线上流量进行资源初始化加载,由于流量太大,初始化过程慢,出现大量请求响应超时、阻塞、资源耗尽从而造成刚启动应用宕机。
  • 注册太早:服务存在异步资源加载问题,当服务还未初始化完全就被注册到注册中心,导致调用时资源未加载完毕出现请求响应慢、调用超时报错等现象。
  • 发布态与运行态未对齐:使用 Kubernetes 的滚动发布功能进行应用发布,由于Kubernetes 的滚动发布一般关联的就绪检查机制,是通过检查应用特定端口是否启动作为应用就绪的标志来触发下一批次的实例发布,但在微服务应用中只有当应用完成了服务注册才可对外提供服务调用。因此某些情况下会出现新应用还未注册到注册中心,老应用实例就被下线,导致无服务可用。

无损下线

其中的服务无法及时下线问题,如下图 1 所示:

图1. Spring Cloud 应用消费者无法及时感知提供者服务下线

对于 Spring Cloud 应用,当应用的两个实例 A’ 和 A 中的 A 下线时,由于 Spring Cloud 框架为了在可用性和性能方面做平衡,消费者默认是 30s 去注册中心拉取最新的服务列表,因此 A 实例的下线不能被实时感知,此时消费者继续通过本地缓存继续调用 A 就会出现调用已下线实例出现流量有损。

针对该问题,阿里云微服务引擎 MSE 基于 Java Agent 字节码技术设计实现的无损下线功能如下图 2 所示:

图2. 无损下线方案

在该套无损下线方案中,服务提供者应用仅需接入 MSE,相比一般的有损下线。应用在下线前会有一段自适应等待时期,该时期待下线应用会通过主动通知的方式,向其在自适应等待阶段发送了请求的服务消费者发送下线事件,消费者接收到下线事件后会主动拉取注册中心服务实例列表以便实时感知应用下线事件避免调用已下线实例造成应用下线流量有损。

无损上线

延迟加载是软件框架设计中最常见的一种策略,例如在 Spring Cloud 框架中 Ribbon 组件的拉取服务列表初始化时机默认是要等到服务的第 1 次调用时刻,例如下图 3 是 Spring Cloud 应用中第 1 次和第 2 次通过 RestTemplate 调用远程服务的请求耗时情况:

图3. 应用启动资源初始化与正常运行过程中耗时情况对比

由测试结果可见,第一次调用由于进行了一些资源初始化,耗时是正常情况的数倍之多。因此把新应用发布到线上直接处理大流量极易出现大量请求响应慢,资源阻塞,应用实例宕机的现象。针对该类大流量下应用资源初始化慢问题,MSE 提供的小流量预热功能通过调节刚上线应用所分配的流量帮助其在进行充分预热后再处理正常流量从而对新实例进行保护。小流量预热过程如下图 4 所示:

图4. 小流量服务预热过程 QPS 与启动时间关系图

除了针对上述应用第一次调用初始化慢所造成的有损上线问题,MSE 还提供了资源预建连接、延迟注册、确保 Kubernetes 就绪检查通过前完成服务注册和确保 Kubernetes 就绪检查通过前完成服务预热等一整套无损上线手段来满足各类不同应用的无损上线需求,整套方案如图 5 所示:

图5. MSE 无损上线方案

如何使用 MSE 的无损上下线

接下来将演示阿里云微服务引擎 MSE 在应用发布时提供的无损上下线和服务预热能力最佳实践。假设应用的架构由 Zuul 网关以及后端的微服务应用实例(Spring Cloud)构成。具体的后端调用链路有购物车应用 A,交易中心应用 B,库存中心应用 C,这些应用中的服务之间通过 Nacos 注册中心实现服务注册与发现。

前提条件

开启 MSE 微服务治理

  • 已创建 Kubernetes 集群,请参见创建 Kubernetes 托管版集群[1]
  • 已开通 MSE 微服务治理专业版,请参见开通 MSE 微服务治理[2]

准备工作

注意,本实践所使用的 Agent 目前还在灰度中,需要对应用 Agent 进行灰度升级,升级文档:
https://help.aliyun.com/document_detail/392373.html

应用部署在不同的 Region(暂时仅支持国内 Region)请使用对应的 Agent 下载地址:
http://arms-apm-cn-[regionId].oss-cn-[regionId].aliyuncs.com/2.7.1.3-mse-beta/

注意替换地址中的[RegionId],RegionId 是阿里云 RegionId。

例如 Region 北京 Agent 地址为:http://arms-apm-cn-beijing.oss-cn-beijing.aliyuncs.com/2.7.1.3-mse-beta/

应用部署流量架构图

图6. 演示应用部署架构

流量压力来源

在 spring-cloud-zuul 应用中,如图 6 所示,其分别向 spring-cloud-a 的灰度版本和正常版本以 QPS 为 100 的速率同时进行服务调用。

部署 Demo 应用程序

将下面的内容保存到一个文件中,假设取名为 mse-demo.yaml,并执行 kubectl apply -f mse-demo.yaml 以部署应用到提前创建好的 Kubernetes 集群中(注意因为 demo 中有 CronHPA 任务,所以请先在集群中安装 ack-kubernetes-cronhpa-controller 组件,具体在容器服务-Kubernetes->市场->应用目录中搜索组件在测试集群中进行安装),这里我们将要部署 Zuul,A, B 和 C 三个应用,其中 A、B 两个应用分别部署一个基线版本和一个灰度版本,B 应用的基线版本关闭了无损下线能力,灰度版本开启了无损下线能力。C 应用开启了服务预热能力,其中预热时长为 120 秒。

# Nacos Server
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nacos-servername: nacos-server
spec:replicas: 1selector:matchLabels:app: nacos-servertemplate:metadata:labels:app: nacos-serverspec:containers:- env:- name: MODEvalue: standaloneimage: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latestimagePullPolicy: Alwaysname: nacos-serverresources:requests:cpu: 250mmemory: 512MidnsPolicy: ClusterFirstrestartPolicy: Always# Nacos Server Service 配置
---
apiVersion: v1
kind: Service
metadata:name: nacos-server
spec:ports:- port: 8848protocol: TCPtargetPort: 8848selector:app: nacos-servertype: ClusterIP#入口 zuul 应用
---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-zuul
spec:replicas: 1selector:matchLabels:app: spring-cloud-zuultemplate:metadata:annotations:msePilotAutoEnable: "on"msePilotCreateAppName: spring-cloud-zuullabels:app: spring-cloud-zuulspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jre- name: LANGvalue: C.UTF-8image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1imagePullPolicy: Alwaysname: spring-cloud-zuulports:- containerPort: 20000# A 应用 base 版本,开启按照机器纬度全链路透传
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: spring-cloud-aname: spring-cloud-a
spec:replicas: 2selector:matchLabels:app: spring-cloud-atemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-amsePilotAutoEnable: "on"labels:app: spring-cloud-aspec:containers:- env:- name: LANGvalue: C.UTF-8- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jre- name: profiler.micro.service.tag.trace.enablevalue: "true"image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-aports:- containerPort: 20001protocol: TCPresources:requests:cpu: 250mmemory: 512MilivenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30# A 应用 gray 版本,开启按照机器纬度全链路透传
---            
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: spring-cloud-a-grayname: spring-cloud-a-gray
spec:replicas: 2selector:matchLabels:app: spring-cloud-a-graystrategy:template:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud -amsePilotAutoEnable: "on"labels:app: spring-cloud-a-grayspec:containers:- env:- name: LANGvalue: C.UTF-8- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jre- name: profiler.micro.service.tag.trace.enablevalue: "true"image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-a-grayports:- containerPort: 20001protocol: TCPresources:requests:cpu: 250mmemory: 512MilivenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30# B 应用 base 版本,关闭无损下线能力
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: spring-cloud-bname: spring-cloud-b
spec:replicas: 2selector:matchLabels:app: spring-cloud-bstrategy:template:metadata:annotations:msePilotCreateAppName: spring-cloud-bmsePilotAutoEnable: "on"labels:app: spring-cloud-bspec:containers:- env:- name: LANGvalue: C.UTF-8- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jre- name: micro.service.shutdown.server.enablevalue: "false"- name: profiler.micro.service.http.server.enablevalue: "false"image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-bports:- containerPort: 8080protocol: TCPresources:requests:cpu: 250mmemory: 512MilivenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30# B 应用 gray 版本,默认开启无损下线功能
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: spring-cloud-b-grayname: spring-cloud-b-gray
spec:replicas: 2selector:matchLabels:app: spring-cloud-b-graytemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-bmsePilotAutoEnable: "on"labels:app: spring-cloud-b-grayspec:containers:- env:- name: LANGvalue: C.UTF-8- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-b-grayports:- containerPort: 8080protocol: TCPresources:requests:cpu: 250mmemory: 512Milifecycle:preStop:exec:command:- /bin/sh- '-c'- >-wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep30;exit 0livenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30# C 应用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: spring-cloud-cname: spring-cloud-c
spec:replicas: 2selector:matchLabels:app: spring-cloud-ctemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-cmsePilotAutoEnable: "on"labels:app: spring-cloud-cspec:containers:- env:- name: LANGvalue: C.UTF-8- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-cports:- containerPort: 8080protocol: TCPresources:requests:cpu: 250mmemory: 512MilivenessProbe:tcpSocket:port: 20003initialDelaySeconds: 10periodSeconds: 30#HPA 配置
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:labels:controller-tools.k8s.io: "1.0"name: spring-cloud-b
spec:scaleTargetRef:apiVersion: apps/v1beta2kind: Deploymentname: spring-cloud-bjobs:- name: "scale-down"schedule: "0 0/5 * * * *"targetSize: 1- name: "scale-up"schedule: "10 0/5 * * * *"targetSize: 2
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:labels:controller-tools.k8s.io: "1.0"name: spring-cloud-b-gray
spec:scaleTargetRef:apiVersion: apps/v1beta2kind: Deploymentname: spring-cloud-b-grayjobs:- name: "scale-down"schedule: "0 0/5 * * * *"targetSize: 1- name: "scale-up"schedule: "10 0/5 * * * *"targetSize: 2
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:labels:controller-tools.k8s.io: "1.0"name: spring-cloud-c
spec:scaleTargetRef:apiVersion: apps/v1beta2kind: Deploymentname: spring-cloud-cjobs:- name: "scale-down"schedule: "0 2/5 * * * *"targetSize: 1 - name: "scale-up"schedule: "10 2/5 * * * *"targetSize: 2# zuul 网关开启 SLB 暴露展示页面   
---     
apiVersion: v1
kind: Service
metadata:name: zuul-slb
spec:ports:- port: 80protocol: TCPtargetPort: 20000selector:app: spring-cloud-zuultype: ClusterIP# a 应用暴露 k8s service
---
apiVersion: v1
kind: Service
metadata:name: spring-cloud-a-base
spec:ports:- name: httpport: 20001protocol: TCPtargetPort: 20001selector:app: spring-cloud-a---
apiVersion: v1
kind: Service
metadata:name: spring-cloud-a-gray
spec:ports:- name: httpport: 20001protocol: TCPtargetPort: 20001selector:app: spring-cloud-a-gray# Nacos Server SLB Service 配置
---
apiVersion: v1
kind: Service
metadata:name: nacos-slb
spec:ports:- port: 8848protocol: TCPtargetPort: 8848selector:app: nacos-servertype: LoadBalancer

结果验证一:无损下线功能

由于我们对 spring-cloud-b 跟 spring-cloud-b-gray 应用均开启了定时 HPA,模拟每 5 分钟进行一次定时的扩缩容。

登录 MSE 控制台,进入微服务治理中心->应用列表->spring-cloud-a->应用详情,从应用监控曲线,我们可以看到 spring-cloud-a 应用的流量数据:

gray 版本的流量在 pod 扩缩容的过程中请求错误数为 0,无流量损失。未打标的版本由于关闭了无损下线功能,在 pod 扩缩容的过程中有 20 个从 spring-cloud-a 发到 spring-cloud-b 的请求出现报错,发生了请求流量损耗。

结果验证二:服务预热功能

我们在 spring-cloud-c 应用开启了定时 HPA 模拟应用上线过程,每隔 5 分钟做一次伸缩,在扩缩容周期内第 2 分钟第 0 秒缩容到 1 个节点,第 2 分钟第 10 秒扩容到 2 个节点。

在预热应用的消费端 spring-cloud-b 开启服务预热功能。

在预热应用的服务提供端 spring-cloud-c 开启服务预热功能。预热时长配置为 120 秒。

观察节点的流量,发现节点流量缓慢上升。并且能看到节点的预热开始和结束时间,以及相关的事件。

从上图可以看到开启预热功能的应用重启后的流量会随时间缓慢增加,在一些应用启动过程中需要预建连接池和缓存等资源的慢启动场景,开启服务预热能有效保护应用启动过程中缓存资源有序创建保障应用安全启动从而实现应用上线的流量无损。

方案介绍 & 实操

更多方案设计细节,请点击下方链接观看微服务应用如何实现无损上下线主题直播视频回放:

微服务应用如何实现无损上下线-云栖号-阿里云

原文链接

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

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

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

相关文章

基于 Observable 构建前端防腐策略

简介:To B 业务的生命周期与迭代通常会持续多年,随着产品的迭代与演进,以接口调用为核心的前后端关系会变得非常复杂。在多年迭代后,接口的任何一处修改都可能给产品带来难以预计的问题。在这种情况下,构建更稳健的前端…

动态卡片:富媒体内容井喷式增长下,新一代移动端动态研发的模式

简介:「蚂蚁动态卡片」新品发布会全程回顾 在 iOS 和 Android 系统近期推送的更迭版本中,系统环境已经逐渐发展出了将部分内容和服务前置化展示的趋势。 同时,伴随着富媒体内容井喷式增长以及内容的多样化、年轻化,一款移动应用…

Windows 上创建的文件,上传到 Linux 服务器,文件名乱码?

作者 | 刘光录来源 | TIAP先来说一下问题,在 Windows 下创建的一系列文件,上传到 Linux 服务器后,出现文件名乱码,导致文件无法读取的情况。事情的起因是这样的...最近有这样一个需求:在Java Web工程中读取本地某一个文…

阿里云成为首个通过“虚拟化云平台性能测试(大规模)”的云厂商

简介:2021年7月27日,在可信云大会上,中国信息通信研究院发布了《虚拟化云平台性能评估方法》,同时,宣布了阿里云成为首个通过“虚拟化云平台性能测试(大规模)”的云厂商,并获得“202…

阿里云神龙团队拿下TPCx-BB排名第一的背后技术

简介:阿里云自主研发的神龙大数据加速引擎获得了TPCx-BB SF3000世界排名第一的成绩。 一 背景介绍 近日,TPC Benchmark Express-BigBench(简称TPCx-BB)公布了最新的世界排名,阿里云自主研发的神龙大数据加速引擎获得了TPCx-BB SF3000排名第…

从中国移动财报透视:什么在支撑移动云发展韧性?

8 月 11 日,中国移动公布 2022 年中期业绩报告。报告显示,上半年中国移动营运收入达人民币 4969 亿元,同比增长 12.0%。净利润 703 亿元,同比增长 18.9%,盈利能力全球领先。其中,移动云收入达人民币 234 亿…

vue 前期准备,项目结构

环境 1、node -v 检测 没有就下载node,装到C盘 http://nodejs.cn/download/ 2、vue -v 检测 没有就 npm install -g vue/cli 或者 yarn global add vue/cli 安装脚手架 网址 https://cli.vuejs.org/zh/ 也可以从网址里找到…

如何设计一个复杂的业务系统?从对领域设计、云原生、微服务、中台的理解开始

简介:业级应用架构是在不断的演进和迭代,但是我始终感觉企业应用架构的形成过程是在一种看起来科学的方法论下,但是又不完全科学的过程中实现的。 作者:焦方飞 大年初一,看完中国队 1:3 越南队的比赛,在思…

如何从容应对复杂性

简介:软件的复杂性,是一个很泛的概念。但是一直都是开发过程中的一个难题,本文旨在探讨如何去从容应对复杂性。 作者 | 無涯 来源 | 阿里技术公众号 软件的复杂性,是一个很泛的概念。 但是一直都是开发过程中的一个难题&#xf…

阿里巴巴开源大规模稀疏模型训练/预测引擎DeepRec

简介:经历6年时间,在各团队的努力下,阿里巴巴集团大规模稀疏模型训练/预测引擎DeepRec正式对外开源,助力开发者提升稀疏模型训练性能和效果。 作者 | 烟秋 来源 | 阿里技术公众号 经历6年时间,在各团队的努力下&#…

产学融合如何促进技术创新,英特尔打了个样

作者 | 宋慧 出品 | CSDN 经过多年的积累与扎实科研,中国的科学与技术水平正在达到和超越世界一线水平。这离不开中国有基数庞大的用户和应用场景,为科学界和工业界提供了将理论付诸实践的机会,反复打磨迭代,以提升技术指标。 作…

3大能力升级,云效+钉钉,让研发协作更「敏捷」

简介:你的团队是否面临如下问题:没有敏捷经验,不知道如何落地敏捷或者敏捷实施不规范?研发交付过程信息更新不及时,无法及时跟进交付结果?员工入职离职,多套账号权限管理难?缺乏交付…

阿里云张献涛:自主最强DPU神龙的秘诀

简介:读懂云计算,才能看清DPU热潮。 微信公众号搜索“弹性计算百晓生”,获取更多云计算知识。 如果细数最近火爆的科技概念,DPU必然位列其中。 这是英伟达一手捧红的新造富故事,是2021年SoC领域最热火朝天的创业赛道…

Gartner发布2022年新兴技术成熟度曲线,推动沉浸式、AI自动化发展

编辑 | 宋慧 供稿 | Gartner Gartner 2022年新兴技术成熟度曲线列出了25项值得关注的新兴技术,这些技术正在推动沉浸式体验的发展和扩展、加速人工智能(AI)自动化并优化技术人员交付。 Gartner研究副总裁Melissa Davis表示:“新兴…

阿里云张献涛:公共云正不断向外延伸,一云多态是未来趋势

简介:一云多态是公有云的未来趋势,包括产品的多形态、部署的多形态和生态的多形态。 编者按:2021年10月22日,在云栖大会《一云多形态部署最佳实践》分论坛,阿里巴巴集团研究员、阿里云弹性计算产品线负责人张献涛发表…

4种典型限流实践保障应用高可用|云效工程师指北

简介:4种典型限流实践保障应用高可用,本文总结了一份AHAS限流实践指南,如果你的系统有被恶意用户攻击的风险,或者系统中某个应用出现异常可能会造成雪崩效应,那么这篇文章会对你有所帮助。 大家好,我叫黄博…

阿里巴巴云原生大数据运维平台 SREWorks 正式开源

简介:阿里巴巴云原生大数据运维平台 SREWorks,沉淀了团队近10年经过内部业务锤炼的 SRE 工程实践,今天正式对外开源,秉承“数据化、智能化”运维思想,帮助运维行业更多的从业者采用“数智”思想做好高效运维。 作者 | …

阿里云 VPC 内网性能测试最佳实践

简介:本文介绍了在阿里云 VPC 内网执行性能测试的方法。相较于传统的公网性能测试,VPC 内网性能测试完全在客户 VPC 环境进行,无需暴露服务到公网,安全性更高,灵活性更强。 作者:风起 背景 随着互联网的快速发展&am…

​在可视化大屏中轻松完成机器学习建模和调参应用实例

Streamlit 是一个开源 Python 库,可帮助开发人员为其系统创建交互式图形用户界面。它专为机器学习和数据科学家团队设计。使用 Streamlit,我们可以快速创建交互式 Web 应用程序并进行部署。前端工作对数据科学家来说并不重要,他们只想要一个小…

EventBridge 事件总线及 EDA 架构解析

简介:EventBridge 是事件驱动的具体落地产品,也是 EDA 的最佳实践方式。 作者:肯梦 作为 Gartner 定义的 10 大战略技术趋势之一,事件驱动架构(EDA)逐渐成为主流技术架构。根据 Gartner 的预估&#xff0…