微服务应用实现无损上下线实践
简介:本文是阿里云微服务引擎MSE在应用发布时提供的无损上下线和服务预热能力最佳实践介绍。
本文是阿里云微服务引擎MSE在应用发布时提供的无损上下线和服务预热能力最佳实践介绍。假设应用的架构由Zuul网关以及后端的微服务应用实例(Spring Cloud)构成。具体的后端调用链路有购物车应用A,交易中心应用B,库存中心应用C,这些应用中的服务之间通过Nacos注册中心实现服务注册与发现。
前提条件
开启 MSE 微服务治理
- 已创建Kubernetes集群,请参见创建Kubernetes托管版集群。
- 已开通MSE微服务治理专业版,请参见开通MSE微服务治理。
背景信息
很多用户量大并发度高的应用系统为了避免发布过程中的流量有损一般选择在流量较小的半夜发布,虽然这样做有效果,但不可控导致背后的研发运维人员经常因为发布问题时常搞得半夜胆战心惊,心力疲惫。基于此,阿里云微服务引擎MSE通过在应用发布过程中,通过应用下线主动实时注销,应用上线健康就绪检查与生命周期对齐以及服务预热等技术手段所提供的微服务应用无损上下线发布功能,让研发运维人员即使是在白天发布应用,也能风轻云淡。
准备工作
注意,本实践所使用的 Agent 目前还在灰度中,需要对应用 Agent 进行灰度升级,升级文档:灰度升级微服务治理Agent - 微服务引擎MSE - 阿里云
应用部署在不同的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/
应用部署流量架构图
流量压力来源
在 spring-cloud-zuul
应用中,每个 pod 具备并发为 10 的访问本地 zuul 端口的 127.0.0.1:20000:/A/a
的http请求流量。可以通过环境变量 demo.qps
配置并发数。
部署 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-server
name: nacos-server
spec:
replicas: 1
selector:
matchLabels:
app: nacos-server
template:
metadata:
labels:
app: nacos-server
spec:
containers:
- env:
- name: MODE
value: standalone
image: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latest
imagePullPolicy: Always
name: nacos-server
resources:
requests:
cpu: 250m
memory: 512Mi
dnsPolicy: ClusterFirst
restartPolicy: Always
# Nacos Server Service 配置
---
apiVersion: v1
kind: Service
metadata:
name: nacos-server
spec:
ports:
- port: 8848
protocol: TCP
targetPort: 8848
selector:
app: nacos-server
type: ClusterIP
#入口 zuul 应用
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-zuul
spec:
replicas: 1
selector:
matchLabels:
app: spring-cloud-zuul
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-zuul
labels:
app: spring-cloud-zuul
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: LANG
value: C.UTF-8
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1
imagePullPolicy: Always
name: spring-cloud-zuul
ports:
- containerPort: 20000
# A 应用 base 版本,开启按照机器纬度全链路透传
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a
msePilotAutoEnable: "on"
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: profiler.micro.service.tag.trace.enable
value: "true"
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# A 应用 gray 版本,开启按照机器纬度全链路透传
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a-gray
name: spring-cloud-a-gray
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a-gray
strategy:
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
msePilotAutoEnable: "on"
labels:
app: spring-cloud-a-gray
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: profiler.micro.service.tag.trace.enable
value: "true"
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a-gray
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# B 应用 base 版本,关闭无损下线能力
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
strategy:
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-b
msePilotAutoEnable: "on"
labels:
app: spring-cloud-b
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: micro.service.shutdown.server.enable
value: "false"
- name: profiler.micro.service.http.server.enable
value: "false"
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# B 应用 gray 版本,默认开启无损下线功能
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b-gray
name: spring-cloud-b-gray
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b-gray
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-b
msePilotAutoEnable: "on"
labels:
app: spring-cloud-b-gray
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-b-gray
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
lifecycle:
preStop:
exec:
command:
- /bin/sh
- '-c'
- >-
wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
30;exit 0
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# C 应用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-c
msePilotAutoEnable: "on"
labels:
app: spring-cloud-c
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 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/v1beta2
kind: Deployment
name: spring-cloud-b
jobs:
- 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/v1beta2
kind: Deployment
name: spring-cloud-b-gray
jobs:
- 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/v1beta2
kind: Deployment
name: spring-cloud-c
jobs:
- 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: 80
protocol: TCP
targetPort: 20000
selector:
app: spring-cloud-zuul
type: ClusterIP
# a 应用暴露 k8s service
---
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-base
spec:
ports:
- name: http
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
---
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-gray
spec:
ports:
- name: http
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a-gray
# Nacos Server SLB Service 配置
---
apiVersion: v1
kind: Service
metadata:
name: nacos-slb
spec:
ports:
- port: 8848
protocol: TCP
targetPort: 8848
selector:
app: nacos-server
type: 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 秒。
观察节点的流量,发现节点流量缓慢上升。并且能看到节点的预热开始和结束时间,以及相关的事件。
从上图可以看到开启预热功能的应用重启后的流量会随时间缓慢增加,在一些应用启动过程中需要预建连接池和缓存等资源的慢启动场景,开启服务预热能有效保护应用启动过程中缓存资源有序创建保障应用安全启动并做到流量无损。
原文链接
本文为阿里云原创内容,未经允许不得转载。
微服务应用实现无损上下线实践相关推荐
- 微服务引擎的线上流量治理最佳实践
简介:本实践将重点介绍如何快速集成主流开源微服务框架,实现业务零改造,解决开源框架在生产落地过程中的痛点,例如无损上下线.标签路由等,并通过托管微服务开源组件(API网关.注册中心.配置中心等)的服务 ...
- 微服务架构深度解析与最佳实践-第一部分:微服务发展历程和定义
微服务架构的概念,现在对于大家应该都不陌生,无论使用 Apache Dubbo.还是 Spring Cloud,都可以去尝试微服务,把复杂而庞大的业务系统拆分成一些更小粒度且独立部署的 Rest 服务 ...
- 微服务架构深度解析与最佳实践 - 第七部分:全文总结与引用材料
最佳实践的总结 林林总总说了这么多的微服务架构相关的知识也好,经验也罢,不一定适合每个希望做微服务系统的技术人员的实际需求."道无常道,法无常法,君子审时度势,自可得而法".实际项 ...
- 微服务架构深度解析与最佳实践
微服务架构深度解析与最佳实践 微服务架构的概念,现在对于大家应该都不陌生,无论使用 Apache Dubbo.还是 Spring Cloud,都可以去尝试微服务,把复杂而庞大的业务系统拆分成一些更小粒 ...
- 【微服务架构】一文读懂单片到微服务架构的模式和最佳实践
在本文中,我们将学习如何使用设计模式.原则和最佳实践来设计微服务架构.我们将使用正确的架构设计模式和技术. 在本文结束时,您将了解如何在微服务分布式架构上设计系统以实现高可用性.高可扩展性.低延迟和对 ...
- 微服务框架 SpringCloud微服务架构 分布式事务 38 动手实践 38.2 实现XA 模式
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] 分布式事务 文章目录 微服务 ...
- 【6】使用dockerfile打包/运行微服务项目,并上传到私服harbor
使用dockerfile打包/运行微服务项目,并上传到私服harbor 关键词 dockerfile自定义demodocker 镜像 把自定义镜像上传到私服harbor 一.环境准备 主机地址 部署 ...
- 【推荐】2020,2021网易数字+大会(云原生微服务+大数据数据库+网易AI实践集合+其他) - (共187份)
[推荐]2020,2021网易数字+大会(云原生&微服务+大数据&数据库+网易AI实践集合+其他) - (共187份) 下载地址:https://download.csdn.net/d ...
- 【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 将微服务运行在Docker上
文章目录 将微服务运行在Docker上 使用Maven插件构建Docker镜像 使用Maven插件读取Dockerfile进行构建 将插件绑定在某个phase执行 参考 源代码 将微服务运行在Dock ...
最新文章
- MySQL server PID file could not be found!
- linux poll in,Linux poll机制详细讲解
- 如何用我python抓取关键字新闻_用python机器学习实现新闻关键词的抽取
- 保证java的jar包在后台运行
- Mahout学习路线图
- 与容器服务 ACK 发行版的深度对话第二弹:如何借助 hybridnet 构建混合云统一网络平面
- Chapter 7:Statistical-Model-Based Methods
- PHP无限极分类生成树方法,无限分级
- 解决easyExcel和poi版本冲突问题
- 计算机网络学习笔记(2. 什么是网络协议)
- 大规模细粒度分类和特定领域的迁移学习
- 数据库没有备份---应如何还原丢失的数据
- 微信小程序中识别html标签的方法
- [剑指offer] 46. 孩子们的游戏(圆圈中最后剩下的数)
- idea启动日志在哪里_艹,我的日志被Intellij IDEA 控制台给“吃”了!
- Tor出现需要控制密码的解决办法
- 在线网站\本地软件拓扑图\复杂网络绘制
- RSF-Center,集群模式下-协调数据结构
- android edittext背景颜色,Android 设置 EditText 背景颜色、背景图片
- java.net.UnknownHostException:
热门文章
- JAVA入门级教学之(内存中的空指针异常)
- fortify hp 价格_惠普推出“惠普Fortify软件安全中心套件”
- 数据结构实验之图论九:最小生成树_初高中数学竞赛训练----图论初步2
- lstm原文_LSTM模型与水文模型在径流模拟中的比较
- windows。forms.timer设置第一次不等待_面试官:换人!他连 TCP 这几个参数都不懂(一)...
- 计算机基础知识的重点,计算机基础知识重点
- 【LeetCode笔记】剑指 Offer 62. 圆圈中最后剩下的数字(Java、约瑟夫环、链表)
- 南充一中计算机机房被盗,成都理工大学与南充市第一中学共建优质生源基地
- mysql utf8mb4 造成慢_mysql使用utf8mb4经验吐血总结
- python web开发项目 源码_Python + Flask 项目开发实践系列七