基于阿里云微服务引擎 MSE 的全链路灰度实践

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 全链路灰度一直是微服务治理的核心关注点,本文一步步的教程介绍如何基于阿里云微服务引擎 MSE 完成全链路灰度发布。


前提条件

本文假设您的 ACK 集群已经创建完成。

开启 MSE 微服务治理

  • 安装 ack-kubernetes-cronhpa-controller ,安装步骤请参考之前的说明
  • 安装 ack-ingress-nginx安装步骤请参考之前的说明
  • 访问 MSE 控制台,在K8s集群列表中选择相应集群,点击管理,选择default 命名空间,点击开启服务治理能力。


开启 AHAS 应用防护

  • 点击开通 AHAS 应用防护 以使用应用流控能力,请注意,需要开通 AHAS 流量防护专业版

  • 访问容器服务控制台,打开应用目录,搜索 ack-ahas-sentinel-pilot ,选择对应集群,点击创建。


部署 Demo 应用程序


将下面的文件保存到 mse-demo.yaml 中,并执行 kubectl apply -f mse-demo.yaml 以部署应用,这里我们将要部署 zuul,A, B, C 三个应用,其中 A、B 两个应用分别部署一个基线版本和一个灰度版本,B应用的基线版本关闭了无损下线能力,灰度版本开启了无损下线能力。C应用有一个 spring-cloud-c-warmup 应用,开启了服务预热能力,其中预热时长为2分钟。


# 入口 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
        alibabacloud.com/burst-resource: eci
      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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/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
        ahasPilotAutoEnable: "on"        ahasAppName: spring-cloud-a
        armsPilotAutoEnable: "on"        armsPilotCreateAppName: spring-cloud-a
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a
        ports:        - containerPort: 20001          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        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
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a-gray
        ports:        - containerPort: 20001          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        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
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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"        - name: profiler.micro.service.warmup.enable
          value: "true"        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b
        ports:        - containerPort: 8080          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        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
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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
        - name: profiler.micro.service.warmup.enable
          value: "true"        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b-gray
        ports:        - containerPort: 8080          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        livenessProbe:          tcpSocket:            port: 20002          initialDelaySeconds: 10          periodSeconds: 30        lifecycle:            preStop:              exec:                command:                  - /bin/sh
                  - '-c'                  - >-
                    wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
                    30;exit 0
# 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
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-c
        ports:        - containerPort: 8080          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        livenessProbe:          tcpSocket:            port: 20003          initialDelaySeconds: 10          periodSeconds: 30# C 应用 warmup 版本---apiVersion: apps/v1
kind: Deployment
metadata:  labels:    app: spring-cloud-c-warmup
  name: spring-cloud-c-warmup
spec:  replicas: 1  selector:    matchLabels:      app: spring-cloud-c-warmup
  template:    metadata:      annotations:        msePilotCreateAppName: spring-cloud-c-warmup
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      labels:        app: spring-cloud-c-warmup
    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.warmup.enable
          value: "true"        - name: profiler.micro.service.warmup.time
          value: "120"        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: spring-cloud-c-warmup
        ports:        - containerPort: 8080          protocol: TCP
        resources:          requests:            cpu: '4'            memory: 8Gi
        livenessProbe:          tcpSocket:            port: 20003          initialDelaySeconds: 10          periodSeconds: 30        lifecycle:            preStop:              exec:                command:                  - /bin/sh
                  - '-c'                  - >-
                    wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
                    30;exit 0
# 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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/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
#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 */4 * * * *"     targetSize: 2   - name: "scale-up"     schedule: "2 */4 * * * *"     targetSize: 4---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 */5 * * * *"     targetSize: 2   - name: "scale-up"     schedule: "3 */5 * * * *"     targetSize: 4---apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:  labels:    controller-tools.k8s.io: "1.0"  name: spring-cloud-c-warmup
spec:   scaleTargetRef:      apiVersion: apps/v1beta2
      kind: Deployment
      name: spring-cloud-c-warmup
   jobs:   - name: "scale-down"     schedule: "0 */4 * * * *"     targetSize: 0   - name: "scale-up"     schedule: "1 */4 * * * *"     targetSize: 1# 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
# 为 zuul 网关开启 Ingress---apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:  name: zuul
spec:  rules:    - http:        paths:          - backend:              serviceName: zuul-slb
              servicePort: 80            path: /


流量压力来源

spring-cloud-zuul应用中,每个 pod 具备并发为 100 qps 的访问本地 zuul 端口的 127.0.0.1:20000:/A/a 的http请求流量,另外有10 qps 会访问 127.0.0.1:20000:/A/a并且带上 x-mse-tag=gray这个header,当前 zuul 的 pod 数为1,所以 spring-cloud-a 应用的平均qps为 110。压力可以通过 环境变量 demo.qps来调节压力大小,默认为100

流量架构图如下:

结果验证

MSE 场景一:对经过机器的流量进行自动染色,实现全链路灰度

我们在 MSE 控制台对 spring-cloud-a  应用配置如下流量比例规则,由于我们对 spring-cloud-a 应用增加了

profiler.micro.service.tag.trace.enable=true 的开关,spring-cloud-a 应用会对经过他的流量进行染色透传,从而实现全链路灰度。

spring-cloud-a中,灰度分组的流量是10,基线分组的流量是100.


spring-cloud-b 中,灰度分组的流量是也是10,基线分组的流量是100.


找到 容器服务对外暴露的 Ingress 的端点。


在命令行中输入以下命令,发现正常的流量走到基线的机器上


curl http://$IP/A/a
A[172.16.2.16] -> B[172.16.2.20] -> C[172.16.2.21]


在命令行中输入一下命令,带上特殊的 header ,发现灰度的流量走到灰度的机器上,并且会向后透传经过 A 和 B 的灰度机器,最后回到 C的基线版本中。


curl-H"x-mse-tag:gray" http://$IP/A/a
Agray[172.16.2.23] -> Bgray[172.16.2.18] -> C[172.16.2.21]



MSE 场景二:服务预热


我们在 spring-cloud-c-warmup 应用开启了定时HPA模拟应用启动的过程,同时对spring-cloud-c-warmup 应用开启了默认2分钟时长的预热功能 profiler.micro.service.warmup.time=120

可以直接在spring-cloud-c-warmup应用直观地看到效果

从上图可以看出来流量缓慢增大,直观地服务预热看到服务预热的效果。

MSE 场景三:无损下线

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


我们可以直接从 spring-cloud-a应用的监控看出来,未开启无损下线功能的监控存在错误。而 gray的流量因为默认开启了无损下线功能,流量默认无损。

可以看到gray的流量在pod扩缩容的过程中无流量损失,未打标的流量由于关闭了无损下线功能,在pod扩缩容的过程中流量出现了损失,如上图所示未打标的流量有 122 的请求错误。

通过 AHAS 实现限流降级


打开 AHAS 控制台 ,找到 spring-cloud-a 应用,选择接口详情,找到 /a 接口,点击 + 好号新增流控规则

选择流控规则,输入单机 QPS 限流阈值 10,点击下一步,最后点击新增。

点击新增添加流控规则


等待约 10s 左右,观察 接口的 QPS 情况,发现通过 QPS  从 100 下降到 20,拒绝 QPS 从 0 上升到 80,因为 spring-cloud-a 有两台机器,因此总的通过 QPS 为 20.

接下来,将该限流规则关闭

观察 QPS , 发现 通过 QPS 回到 100,拒绝 QPS 降低为 0。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
17天前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 云原生 API 网关 2024 年 11 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
21天前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
21天前
|
算法 NoSQL Java
微服务架构下的接口限流策略与实践#### 一、
本文旨在探讨微服务架构下,面对高并发请求时如何有效实施接口限流策略,以保障系统稳定性和服务质量。不同于传统的摘要概述,本文将从实际应用场景出发,深入剖析几种主流的限流算法(如令牌桶、漏桶及固定窗口计数器等),通过对比分析它们的优缺点,并结合具体案例,展示如何在Spring Cloud Gateway中集成自定义限流方案,实现动态限流规则调整,为读者提供一套可落地的实践指南。 #### 二、
47 3
|
24天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
78 5
|
20天前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
32 1
|
21天前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
37 2
|
21天前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
39 1
|
22天前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。
|
22天前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####
|
19天前
|
Cloud Native API 持续交付
云原生架构下的微服务治理策略与实践####
本文旨在探讨云原生环境下微服务架构的治理策略,通过分析当前面临的挑战,提出一系列实用的解决方案。我们将深入讨论如何利用容器化、服务网格(Service Mesh)等先进技术手段,提升微服务系统的可管理性、可扩展性和容错能力。此外,还将分享一些来自一线项目的经验教训,帮助读者更好地理解和应用这些理论到实际工作中去。 ####
35 0

相关产品

  • 微服务引擎