基于消息队列RocketMQ实现全链路灰度 本章节介绍如何基于消息队列RocketMQ实现全链路灰度 概述 本文介绍在使用消息队列(RocketMQ)这种异步场景下,可以在不修改业务代码的情况下,实现异步场景的灰度,从而实现全链路灰度。本文介绍基于消息队列RocketMQ实现全链路灰度。 背景介绍 在大多数业务场景中对于消息的灰度并没有RPC调用那么严格,但是当全链路灰度调用中涉及到消息消费时,如果消息消费没有按照全链路流量规则路由,则会导致通过消息产生的流量逃逸,从而破坏全链路规则,导致出现一些不符合预期的情况。 如下图所示,本文分别部署网关、appa、appagray、appb、appbgray、appc、appcgray以及RocketMQ,模拟一个真实的全链路灰度场景。 通过网关调用appa应用的接口,当满足路由规则后,灰度流量会被路由到appagray,appagray又会调用appbgray,随后由appbgray发送灰度消息,appcgray将会收到灰度消息,而appc不会收到灰度消息。 前提条件 1. 用户已开通微服务治理中心企业版。 2. 用户已开通云容器引擎。 3. 用户已部署RocketMQ,且RocketMQ版本在4.5.0以上,broker.conf中已配置enablePropertyFiltertrue。 部署Demo应用 准备自建入口网关msgczuul,准备应用msgcappa,msgcappb和msgcappc。调用过程是msgcappa –> msgcappb > msgcappc。 步骤1:在云容器引擎中安装微服务治理插件: 1. 登录“云容器引擎”控制台。 2. 在左侧菜单栏选择“集群”,点击目标集群。 3. 在集群管理页面点击“插件”“插件市场”,选择“cubems”插件安装。 步骤2:为应用开启微服务治理能力: 1. 登录“云容器引擎”控制台。 2. 左侧菜单栏选择“集群”,点击目标集群。 3. 在集群管理页面点击“工作负载”“无状态”,选择目标命名空间。 4. 在Deployment列表页选择指定Deployment,并点击“全量替换”,进入Deployment编辑页。 5. 在Deployment编辑页点击“显示高级设置”,新增“Pod标签”: mseCubeMsAutoEnable:on。 6. 在发布应用时,配置指定环境变量,可指定注入微服务治理中心的应用名、命名空间和标签等信息。 环境变量配置如下: 环境变量名 环境变量值 MSEAPPNAME 接入到微服务治理中心的应用名。 MSESERVICETAG 应用标签信息,如灰度应用可配置gray。 MSENAMESPACE(选填) 接入到微服务治理中心的命名空间,默认为:default。 7. 完成编辑后点击“提交”,重新发布容器即可接入。 appa应用的配置 基线: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appa" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appa" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appa" spec: containers: env: name: "MSEAPPNAME" value: "appa" image: "镜像仓库域名/xxx/appa:latest" imagePullPolicy: "Always" name: "appa" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" 灰度: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appa" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appa" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appa" spec: containers: env: name: "MSEAPPNAME" value: "appa" name: "MSESERVICETAG" value: "gray" image: "镜像仓库域名/xxx/appa:latest" imagePullPolicy: "Always" name: "appa" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" appb应用的配置 基线: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appb" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appb" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appb" spec: containers: env: name: "MSEAPPNAME" value: "appb" image: "镜像仓库域名/xxx/appb:latest" imagePullPolicy: "Always" name: "appb" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" 灰度: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appb" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appb" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appb" spec: containers: env: name: "MSEAPPNAME" value: "appb" name: "MSESERVICETAG" value: "gray" image: "镜像仓库域名/xxx/appb:latest" imagePullPolicy: "Always" name: "appb" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" appc应用的配置 基线: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appc" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appc" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appc" spec: containers: env: name: "MSEAPPNAME" value: "appc" image: "镜像仓库域名/xxx/appc:latest" imagePullPolicy: "Always" name: "appc" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" 灰度: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "appc" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "appc" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "appc" spec: containers: env: name: "MSEAPPNAME" value: "appc" name: "MSESERVICETAG" value: "gray" image: "镜像仓库域名/xxx/appc:latest" imagePullPolicy: "Always" name: "appc" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi" zuul应用的配置: apiVersion: "apps/v1" kind: "Deployment" metadata: name: "zuul" namespace: "default" spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: name: "zuul" template: metadata: labels: mseCubeMsAutoEnable: "on" name: "zuul" spec: containers: env: name: "MSEAPPNAME" value: "zuul" image: "镜像仓库域名/xxx/zuul:latest" imagePullPolicy: "Always" name: "zuul" ports: containerPort: 26160 livenessProbe: tcpSocket: port: 26160 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "1" memory: "1Gi"