赞
踩
作者:泮圣伟(十眠)
全链路灰度是微服务最核心的功能之一,也一直是云上客户在微服务化深入过程中必须具备的功能。全链路灰度因为涉及到的技术、场景众多,如果云上企业一一自己实现,需要花费大量人力成本对其进行扩展与运维。
RPC: 微服务之间的路由
MQ
Database
Redis
分布式任务调度
前端
可观测性
目前 MSE 服务治理专业版提供了完整的产品化的全链路灰度解决方案,覆盖 RPC、MQ、可观测性等绝大多数场景。只要您的架构是基于 Spring Cloud 或者 Dubbo 框架,您的应用无需升级,无需一行代码改动,即可玩转企业级全链路灰度功能。
1) 通过设置流量规则对所需流量进行’染色’,'染色’流量会路由到灰度机器。
2) 灰度流量携带灰度标往下游传递,形成灰度专属环境流量泳道,无灰度环境应用会默认选择未打标的基线环境。
未打标的应用属于基线稳定版本的应用,即稳定的线上环境。当我们将发布对应的灰度版本代码,然后可以配置规则定向引入特定的线上流量,控制灰度代码的风险。
流量规则定制后,可根据需求进行一键停启,增删改查,实时生效。灰度引流更便捷。
具备泳道级别的单应用可观测能力
同时具备全链路应用的可观测能力,可以从全局视角观察流量是否存在逃逸情况。灰没灰到,一目了然。
MSE 微服务治理能力基于 Java Agent 字节码增强的技术实现,无缝支持市面上近5年的所有 Spring Cloud 和 Dubbo 的版本,用户不用改一行代码就可以使用,不需要改变业务的现有架构,随时可上可下,没有绑定。只需开启 MSE 微服务治理专业版,在线配置,实时生效。
应用开启 MSE 微服务治理后就具备无损上下线能力,大流量下的发布、回滚、扩容、缩容等场景,均能保证流量无损。
接下来将演示全链路灰度的能力,我们使用应用的架构由 Ingress-nginx 以及后端的微服务架构(Spring Cloud)来组成,后端调用链路有3跳,购物车(a),交易中心(b),库存中心(c),客户端通过 客户端或者是 H5 页面来访问后端服务,他们通过 Nacos 注册中心做服务发现。
登录 MSE 治理中心控制台,如果您尚未开通 MSE 微服务治理,请根据提示开通专业版。如果您已经开通了 MSE 微服务治理基础版,请根据概览页中右侧的提示,升级到 专业版。
将下面的文件保存到 ingress-gray-demo-deployment-set.yaml 中,并执行 kubectl apply -f ingress-gray-demo-deployment-set.yaml 以部署应用,这里我们将要部署 A, B, C 三个应用,每个应用分别部署一个基线版本和一个灰度版本。
# A 应用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a spec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: annotations: msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # A 应用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a-new ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # B 应用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b spec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: annotations: msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b spec: containers: - env: - 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 ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # B 应用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-b-new template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b-new spec: containers: - env: - 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-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # C 应用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c spec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: annotations: msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c spec: containers: - env: - 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 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # C 应用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c-new spec: containers: - env: - 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: IfNotPresent name: spring-cloud-c-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # Nacos Server --- apiVersion: apps/v1 kind: Deployment metadata: 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: nacos/nacos-server:latest imagePullPolicy: Always name: nacos-server 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
针对入口应用 A ,配置两个 k8s service, spring-cloud-a-base 对应 A 的 base 版本,spring-cloud-a-gray 对应 A 的 gray 版本。
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-new
泳道为相同版本应用定义的一套隔离环境。只有满足了流控路由规则的请求流量才会路由到对应泳道里的打标应用。一个应用可以属于多个泳道,一个泳道可以包含多个应用,应用和泳道是多对多的关系。
泳道组:泳道的集合。泳道组的作用主要是为了区分不同团队或不同场景。
登录 MSE 治理中心控制台 [2] ,找到 微服务治理中心 > 全链路灰度
可以看到我们需要实现上述描述的能力,我们只需要两个步骤,创建泳道组与创建泳道
点击创建泳道组按钮,并选择我们泳道组涉及到的后端微服务应用,按照上述 demo 来看就是 A, B, C 三个应用
在全链路灰度页面上方选择创建和泳道组时相同的微服务空间,然后底部单击点击创建第一个分流泳道。需要注意的是 加入全链路流量控制的应用,将不再支持金丝雀发布、标签路由等功能。
按照产品的 Step 来,我们分别需要起一个泳道名称,配置应用标签,选择泳道关联的标签,去 ACK 控制台配置 Ingress 的路由规则。
查看泳道,分别有两种模式
配置入口的 Ingress 规则,访问 www.base.com 路由到 a 应用的 base 版本,访问 www.gray.com 路由到 a 应用的 gray 版本。
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: spring-cloud-a-base spec: rules: - host: www.base.com http: paths: - backend: serviceName: spring-cloud-a-base servicePort: 20001 path: / --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: spring-cloud-a-gray spec: rules: - host: www.gray.com http: paths: - backend: serviceName: spring-cloud-a-gray servicePort: 20001 path: /
访问 www.base.com 路由到基线环境
curl -H"Host:www.base.com" http://{ingress-ip}/a
A[172.18.144.155] -> B[172.18.144.120] -> C[172.18.144.79]%
此时,访问 www.gray.com 路由到灰度环境
curl -H"Host:www.gray.com" http://{ingress-ip}/a
Agray[172.18.144.160] -> Bgray[172.18.144.57] -> Cgray[172.18.144.157]%
在全链路灰度页面选择目标泳道组。在涉及应用中选择对应的应用,即可出现相应的流量视图
除了查看单个应用的监控图监控图外,我们还可以查看泳道组内所有应用的监控图。通过比对分析所有应用的监控图,可以分析出更多有用信息。
MSE 服务治理的全链路灰度产品化能力还在不断演进,目前我们支持了 MQ、RPC、可观测等,后续还会支持 XXL-JOB 等更多的场景,目前我们有如何在 MSE 上实现多语言微服务治理 [3] 、使用 Cloud Toolkit 实现微服务的端云互联 [4] 、基于 Ingress-nginx 网关实现全链路灰度 [5] 、基于 MSE 云原生网关实现全链路灰度 [6] 、基于自建 Spring Cloud Gateway 或 Zuul 网关实现全链路灰度 [7] 、基于消息队列 RocketMQ 版实现全链路灰度 [8] 、通过 Jenkins 构建 CI/CD 实现金丝雀发布 [9] 、微服务敏捷开发最佳实践 [10] 等全链路灰度相关的完整解决方案,随着用户场景与实践的增多,我们的解决方案还会不断迭代与丰富。
MSE 服务治理帮助我们系统以很低的成本无侵入的方式快速实现了全链路灰度能力,进一步提升了我们系统的稳定性,让我们新需求的迭代上线更加地安心。
-- 来电科技架构师 汤长征
来电科技自 2014 年起开始进入共享充电领域,定义并开创了行业,属于行业内最早的共享充电企业。主要业务覆盖充电宝自助租赁、定制商场导航机开发、广告展示设备及广告传播等服务。来电科技拥有业内立体化产品线,大中小机柜以及桌面型,目前全国超过 90%的城市实现业务服务落地,注册用户超 2 亿人,实现全场景用户需求。
来电的业务架构如下,最上层是移动端等用户界面,自建的 Nginx 网关作为接入层,服务层就是各种服务,使用的是 Spring Cloud 与 Dubbo 作为服务框架。
来电科技全链路灰度落地的架构如下:
在 Nginx 层配置流量分流的配置,10% 的流量进入灰度环境,90% 的流量进入未打标即线上正式环境,然后经过灰度环境的流量会自动被 MSE 染上对应环境的颜色,从而进行全链路的灰度路由,保证流量在灰度环境中闭环,如果没有灰度环境的机器,比如支付中心只有线上的机器,那么流量会走线上环境,当我们数据中心有存在灰度环境的机器,那么灰度流量还会重新回到数据中心的灰度环境中。
MSE 的全链路灰度能力随着客户场景的深入而不断扩展与迭代,只有经过客户打磨的产品才会愈发历久弥新,欢迎大家尝鲜体验。
[1] 容器服务控制台
https://cs.console.aliyun.com/#/authorize
[2] MSE 治理中心控制台
https://mse.console.aliyun.com/?spm=a2c4g.11186623.2.13.f90a6a60WiEx0N#/auth
[3] 如何在 MSE 上实现多语言微服务治理
https://help.aliyun.com/document_detail/184289.html
[4] 使用 Cloud Toolkit 实现微服务的端云互联
https://help.aliyun.com/document_detail/196920.html
[5] 基于 Ingress-nginx 网关实现全链路灰度
https://help.aliyun.com/document_detail/347790.html
[6] 基于 MSE 云原生网关实现全链路灰度
https://help.aliyun.com/document_detail/359851.html
[7] 基于自建 Spring Cloud Gateway 或 Zuul 网关实现全链路灰度
https://help.aliyun.com/document_detail/359858.html
[8] 基于消息队列 RocketMQ 版实现全链路灰度
https://help.aliyun.com/document_detail/397318.html
[9] 通过 Jenkins 构建 CI/CD 实现金丝雀发布
https://help.aliyun.com/document_detail/384436.html
[10] 微服务敏捷开发最佳实践
https://help.aliyun.com/document_detail/397319.html
点击文末“此处”,了解更多详情~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。