微服务应用实现无损上下线最佳实践

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文是阿里云微服务引擎MSE在应用发布时提供的无损上下线和服务预热能力最佳实践介绍。

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

前提条件

开启 MSE 微服务治理


背景信息

很多用户量大并发度高的应用系统为了避免发布过程中的流量有损一般选择在流量较小的半夜发布,虽然这样做有效果,但不可控导致背后的研发运维人员经常因为发布问题时常搞得半夜胆战心惊,心力疲惫。基于此,阿里云微服务引擎MSE通过在应用发布过程中,通过应用下线主动实时注销,应用上线健康就绪检查与生命周期对齐以及服务预热等技术手段所提供的微服务应用无损上下线发布功能,让研发运维人员即使是在白天发布应用,也能风轻云淡。


准备工作


注意,本实践所使用的 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/


应用部署流量架构图




流量压力来源

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 秒。


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

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

相关文章
|
6天前
|
机器学习/深度学习 人工智能 Java
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
10 1
|
5天前
|
运维 监控 API
打造高效后端:微服务架构在现代应用中的实践
本篇文章探讨了微服务架构在现代应用中的实际应用,重点介绍了其优势、挑战以及最佳实践。通过具体案例和技术细节,我们将深入了解如何设计、实现和维护一个高效的微服务架构,以满足不断变化的业务需求。
18 0
|
10天前
|
设计模式 消息中间件 运维
微服务架构在后端开发中的应用与挑战
微服务架构作为一种现代软件开发方法,带来了灵活性、可扩展性和高效性,但同时也引发了诸如复杂性管理、数据一致性等新的挑战。本文深入探讨了微服务架构在后端开发中的应用场景,以及应对这些挑战的策略。
19 0
|
13天前
|
监控 数据管理 API
探索微服务架构中的后端设计最佳实践
在当今快速发展的技术世界中,微服务架构已经成为开发大型复杂系统的一种标准方法。本篇文章将深入探讨微服务架构在后端设计中的最佳实践,涵盖服务拆分、API设计、数据管理及监控和调试等方面,帮助开发者在实际项目中应用这些原则,以构建高性能、可扩展且易于维护的系统。
19 0
|
13天前
|
监控 负载均衡 持续交付
深入理解微服务架构及其在现代后端开发中的应用
本文将深入探讨微服务架构的核心概念、设计原则和实施挑战,并分析其在现代后端开发中的实际应用。通过比较传统单体应用与微服务的优劣,揭示微服务如何助力于系统的可扩展性、灵活性和持续部署。此外,文章还将讨论微服务实施过程中的常见问题及解决方案,为后端开发者提供实践指导。
|
2天前
|
设计模式 监控 持续交付
深入理解微服务架构:从理论到实践
【6月更文挑战第22天】微服务架构作为现代软件开发的基石,其理念和实践已经深入人心。本文将通过一个实际案例,探讨如何将微服务架构的理论应用到实践中去,包括设计原则、技术选型、以及实施过程中可能遇到的挑战和相应的解决策略。我们将看到,尽管微服务带来了许多优势,但在实际应用中也不可避免地会遇到一系列问题,需要开发者具备深厚的技术功底和丰富的实践经验才能妥善应对。
|
21小时前
|
缓存 运维 监控
探索微服务架构中的API网关模式
在微服务架构的海洋中,API网关是连接客户端与众多微服务群岛之间的桥梁。本文将深入探讨API网关的设计原则、核心功能以及在现代软件架构中的关键作用,同时分析其在实际应用中的效益和面临的挑战。
|
2天前
|
监控 Kubernetes API
探索微服务架构中的API网关模式
【6月更文挑战第22天】在微服务架构的海洋中,API网关是一艘引领航行的旗舰。它不仅是服务的守门人,更是流量的指挥官和信息的翻译官。本文将深入探讨API网关的核心作用、设计考量与实现策略,为构建高效、可靠的微服务系统提供航标。
|
2天前
|
JSON 负载均衡 监控
探索微服务架构中的API网关模式
【6月更文挑战第22天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务间的通信与集成。本文将深入探讨API网关的核心概念、设计原则及其在现代后端系统中的关键作用,同时通过实例分析其对系统性能和可维护性的影响,为读者提供一种视角,理解如何高效地构建和管理微服务架构下的API网关。
|
1天前
|
Kubernetes 监控 Cloud Native
云原生架构下的微服务治理实践
【6月更文挑战第23天】在云计算的浪潮中,云原生架构以其弹性、可扩展性和高效性成为企业数字化转型的重要推手。本文将深入探讨如何利用云原生技术实现微服务的治理与优化,确保系统的稳定性和高可用性。我们将从微服务的基本概念出发,通过具体案例分析,揭示云原生环境下微服务治理的关键策略,并分享实践经验,旨在为读者提供一套完整的微服务治理解决方案。

热门文章

最新文章