用asp做网站系统步骤,店面设计用什么软件,抖音代运营正规公司,网站建设方案标书简介#xff1a;本文将以上次介绍过的《如何用 20 分钟就能获得同款企业级全链路灰度能力#xff1f;》中的场景为基础#xff0c;来进一步介绍消息场景的全链路灰度。
作者#xff1a;亦盏
之前的系列文章中#xff0c;我们已经通过全链路金丝雀发布这个功能来介绍了 M…简介本文将以上次介绍过的《如何用 20 分钟就能获得同款企业级全链路灰度能力》中的场景为基础来进一步介绍消息场景的全链路灰度。
作者亦盏
之前的系列文章中我们已经通过全链路金丝雀发布这个功能来介绍了 MSE 对于全链路流量控制的场景我们已经了解了 Spring Cloud 和 Dubbo 这一类 RPC 调用的全链路灰度应该如何实现但是没有涉及到消息这类异步场景下的流量控制今天我们将以上次介绍过的《如何用 20 分钟就能获得同款企业级全链路灰度能力》中的场景为基础来进一步介绍消息场景的全链路灰度。
虽然绝大多数业务场景下对于消息的灰度的要求并不像 RPC 的要求得这么严格但是在以下两个场景下还是会对消息的全链路有一定的诉求的。
1、第一种场景是在消息消费时可能会产生新的 RPC 调用如果没有在消息这一环去遵循之前设定好的全链路流量控制的规则会导致通过消息产生的这部分流量“逃逸”从而导致全链路灰度的规则遭到破坏导致出现不符合预期的情况。
为了防止出现这个情况我们需要在消费时候将消息里原来的流量标复原并在 RPC 调用的时候遵循原来的规则。我们通过架构图来详细描述一下满足这个逻辑之后调用链路是怎样的从下图中我们可以看到灰度和基线环境生产出来的消息虽然在消息推送的时候是随机的但是在消费过程中产生的新的 RPC 调用还是能够回到流量原来所属的环境。 2、第二种场景需要更加严格的消息灰度隔离。比如当消息的消费逻辑进行了修改时这时候希望通过小流量的方式来验证新的消息消费逻辑的正确性要严格地要求灰度的消息只能被推送给灰度的消息消费者。 今天我们就来实操一下第二种场景消息的全链路灰度目前 MSE 仅支持 RocketMQ 消息的灰度。若您使用的是开源版 RocketMQ那么版本需要在 4.5.0 及以上若您使用的是阿里云商业版 RocketMQ那么需要使用铂金版且 Ons Client 版本在 1.8.0.Final 及以上。如果只是想使用第一种场景只需要给 B 应用开启全链路灰度的功能即可不需要做额外的消息灰度相关的配置。
在这次最佳实践的操作中我们是将应用部署在阿里云容器服务 Kubernetes 版本即 ACK 集群来演示但是事实上消息灰度对于应用的部署模式是没有限制性要求的您可以参考 MSE 帮助文档找到自己所使用的部署模式对应的接入方式也能使用消息全链路灰度。
前提条件
开通 MSE 专业版请参见开通 MSE 微服务治理专业版[1]。创建 ACK 集群请参见创建 Kubernetes 集群[2]。
操作步骤
步骤一接入 MSE 微服务治理
1、安装 mse-ack-pilot
登录容器服务控制台[3]。在左侧导航栏单击市场 应用目录。在应用目录页面点击阿里云应用选择微服务并单击 ack-mse-pilot。在 ack-mse-pilot 页面右侧集群列表中选择集群然后单击创建。安装 MSE 微服务治理组件大约需要 2 分钟请耐心等待。
创建成功后会自动跳转到目标集群的 Helm 页面检查安装结果。如果出现以下页面展示相关资源则说明安装成功。 2、为 ACK 命名空间中的应用开启 MSE 微服务治理
登录 MSE 治理中心控制台[4]如果您尚未开通 MSE 微服务治理请根据提示开通。在左侧导航栏选择微服务治理中心 Kubernetes 集群列表。在 Kubernetes 集群列表页面搜索框列表中选择集群名称或集群 ID然后输入相应的关键字单击搜索图标。单击目标集群操作列的管理。在集群详情页面命名空间列表区域单击目标命名空间操作列下的开启微服务治理。在开启微服务治理对话框中单击确认。
步骤二还原线上场景
首先我们将分别部署 spring-cloud-zuul、spring-cloud-a、spring-cloud-b、spring-cloud-c 这四个业务应用以及注册中心 Nacos Server 和消息服务 RocketMQ Server模拟出一个真实的调用链路。
Demo 应用的结构图下图应用之间的调用既包含了 Spring Cloud 的调用也包含了 Dubbo 的调用覆盖了当前市面上最常用的两种微服务框架。其中 C 应用会生产出 RocketMQ 消息由 A 应用进行消费A 在消费消息时也会发起新的调用。这些应用都是最简单的 Spring Cloud 、 Dubbo 和 RocketMQ 的标准用法您也可以直接在 https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/mse-simple-demo 项目上查看源码。
部署之前简单介绍一下这个调用链路
spring-cloud-zuul 应用在收到 “/A/dubbo” 的请求时会把请求转发给 spring-cloud-a 然后 spring-cloud-a 通过 dubbo 协议去访问 spring-cloud-b spring-cloud-b 也通过 dubbo 协议去访问 spring-cloud-cspring-cloud-c 在收到请求后会生产一个消息并返回自己的环境标签和 ip。这些生产出来的消息会由 spring-cloud-a 应用消费spring-cloud-a 应用在消费消息的时候会通过 spring cloud 去调用 BB 进而通过 spring cloud 去调用 C并且将结果输出到自己的日志中。
当我们调用 /A/dubbo 的时候
返回值是这样 A[10.25.0.32] - B[10.25.0.152] - C[10.25.0.30]同时A 应用在接收到消息之后输出的日志如下2021-12-28 10:58:50.301 INFO 1 --- [essageThread_15] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.25.0.30],invoke result:A[10.25.0.32] - B[10.25.0.152] - C[10.25.0.30]熟悉了调用链路之后我们继续部署应用您可以使用 kubectl 或者直接使用 ACK 控制台来部署应用。部署所使用的 yaml 文件如下您同样可以直接在 https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/mse-simple-demo 上获取对应的源码。
# 部署 Nacos ServerapiVersion: apps/v1
kind: Deployment
metadata:name: nacos-server
spec:selector:matchLabels:app: nacos-servertemplate:metadata:annotations:labels:app: nacos-serverspec:containers:- env:- name: MODEvalue: standaloneimage: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latestimagePullPolicy: IfNotPresentname: nacos-serverports:- containerPort: 8848---
apiVersion: v1
kind: Service
metadata:name: nacos-server
spec:type: ClusterIPselector:app: nacos-serverports:- name: httpport: 8848targetPort: 8848# 部署业务应用
---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-zuul
spec:selector:matchLabels:app: spring-cloud-zuultemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-zuullabels:app: spring-cloud-zuulspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jre- name: enable.mq.invokevalue: trueimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.0imagePullPolicy: Alwaysname: spring-cloud-zuulports:- containerPort: 20000---
apiVersion: v1
kind: Service
metadata:annotations:service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.smallservice.beta.kubernetes.io/alicloud-loadbalancer-address-type: internetname: zuul-slb
spec:ports:- port: 80protocol: TCPtargetPort: 20000selector:app: spring-cloud-zuultype: LoadBalancer
status:loadBalancer: {}---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-a
spec:selector:matchLabels:app: spring-cloud-atemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-alabels:app: spring-cloud-aspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0imagePullPolicy: Alwaysname: spring-cloud-aports:- containerPort: 20001livenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-b
spec:selector:matchLabels:app: spring-cloud-btemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-blabels:app: spring-cloud-bspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:1.0.0imagePullPolicy: Alwaysname: spring-cloud-bports:- containerPort: 20002livenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-c
spec:selector:matchLabels:app: spring-cloud-ctemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-clabels:app: spring-cloud-cspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:1.0.0imagePullPolicy: Alwaysname: spring-cloud-cports:- containerPort: 20003livenessProbe:tcpSocket:port: 20003initialDelaySeconds: 10periodSeconds: 30
---apiVersion: apps/v1
kind: Deployment
metadata:name: rockectmq-broker
spec:selector:matchLabels:app: rockectmq-brokertemplate:metadata:labels:app: rockectmq-brokerspec:containers:- command:- sh- mqbroker- -n- mqnamesrv:9876- -c /home/rocketmq/rocketmq-4.5.0/conf/broker.confenv:- name: ROCKETMQ_HOMEvalue: /home/rocketmq/rocketmq-4.5.0image: registry.cn-shanghai.aliyuncs.com/yizhan/rocketmq:4.5.0imagePullPolicy: Alwaysname: rockectmq-brokerports:- containerPort: 9876protocol: TCP- containerPort: 10911protocol: TCP- containerPort: 10912protocol: TCP- containerPort: 10909---apiVersion: apps/v1
kind: Deployment
metadata:name: rocketmq-name-server
spec:selector:matchLabels:app: rocketmq-name-servertemplate:metadata:labels:app: rocketmq-name-serverspec:containers:- command:- sh- mqnamesrvenv:- name: ROCKETMQ_HOMEvalue: /home/rocketmq/rocketmq-4.5.0image: registry.cn-shanghai.aliyuncs.com/yizhan/rocketmq:4.5.0imagePullPolicy: Alwaysname: rocketmq-name-serverports:- containerPort: 9876protocol: TCP- containerPort: 10911protocol: TCP- containerPort: 10912protocol: TCP- containerPort: 10909protocol: TCP--- apiVersion: v1
kind: Service
metadata:name: mqnamesrv
spec:type: ClusterIPselector:app: rocketmq-name-serverports:- name: mqnamesrv-9876-9876port: 9876targetPort: 9876
安装成功后示例如下
➜ ~ kubectl get svc,deploy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 192.168.0.1 none 443/TCP 7d
service/mqnamesrv ClusterIP 192.168.213.38 none 9876/TCP 47h
service/nacos-server ClusterIP 192.168.24.189 none 8848/TCP 47h
service/zuul-slb LoadBalancer 192.168.189.111 123.56.253.4 80:30260/TCP 47hNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nacos-server 1/1 1 1 4m
deployment.apps/rockectmq-broker 1/1 1 1 4m
deployment.apps/rocketmq-name-server 1/1 1 1 5m
deployment.apps/spring-cloud-a 1/1 1 1 5m
deployment.apps/spring-cloud-b 1/1 1 1 5m
deployment.apps/spring-cloud-c 1/1 1 1 5m
deployment.apps/spring-cloud-zuul 1/1 1 1 5m
同时这里我们可以通过 zuul-slb 来验证一下刚才所说的调用链路
➜ ~ curl http://123.56.253.4/A/dubbo
A[10.25.0.32] - B[10.25.0.152] - C[10.25.0.30]步骤三开启消息灰度功能
现在根据控制台的提示在消息的生产者 spring-cloud-c 和消息的消费者 spring-cloud-a 都开启消息的灰度。我们直接通过 MSE 的控制台开启点击进入应用的详情页选择“消息灰度”标签。 可以看到在未打标环境忽略的标签中我们输入了 gray这里意味着带着 gray 环境标的消息只能由 spring-cloud-a-gray 消费不能由 spring-cloud-a 来消费。
1、这里需要额外说明一下因为考虑到实际场景中spring-cloud-c 应用和 spring-cloud-a 应用的所有者可能不是同一个人不一定能够做到两者同时进行灰度发布同步的操作所以在消息的灰度中未打标环境默认的行为是消费所有消息。这样 spring-cloud-c 在进行灰度发布的时候可以不需要强制 spring-cloud-a 应用也一定要同时灰度发布。
2、我们把未打标环境消费行为的选择权交给 spring-cloud-a 的所有者如果需要实现未打标环境不消费 c-gray 生产出来的消息只需要在控制台进行配置即可配置之后实时生效。
使用此功能您无需修改应用的代码和配置。消息的生产者和消息的消费者需要同时开启消息灰度消息的灰度功能才能生效。消息类型目前只支持 RocketMQ包含开源版本和阿里云商业版。如果您使用开源 RocketMQ则 RocketMQ Server 和 RocketMQ Client 都需要使用 4.5.0 及以上版本。如果您使用阿里云 RocketMQ需要使用铂金版且 Ons Client 使用 1.8.0.Final 及以上版本。开启消息灰度后MSE 会修改消息的 Consumer Group。例如原来的 Consumer Group 为 group1环境标签为 gray开启消息灰度后则 group 会被修改成 group1_gray如果您使用的是阿里云 RocketMQ 请提前创建好 group。默认使用 SQL92 的过滤方式如果您使用的开源 RocketMQ需要在服务端开启此功能即在 broker.conf 中配置 enablePropertyFiltertrue。默认情况下未打标节点将消费所有环境的消息若需要指定 未打标环节点 不消费 某个标签环境生产出来的消息请配置“未打标环境忽略的标签”修改此配置后动态生效无需重启应用。
步骤四重启节点部署新版本应用并引入流量进行验证
首先因为开启和关闭应用的消息灰度功能后都需要重启节点才能生效所以首先我们需要重启一下 spring-cloud-a 和 spring-cloud-c 应用重启的方式可以在控制台上选择重新部署或者直接使用 kubectl 命令删除现有的 pod。 然后继续使用 yaml 文件的方式在 Kubernetes 集群中部署新版本的 spring-cloud-a-gray、spring-cloud-b-gray 和 spring-cloud-c-gray
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-a-gray
spec:selector:matchLabels:app: spring-cloud-a-graytemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-alabels:app: spring-cloud-a-grayspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0imagePullPolicy: Alwaysname: spring-cloud-a-grayports:- containerPort: 20001livenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30
---
apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-b-gray
spec:selector:matchLabels:app: spring-cloud-b-graytemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-blabels:app: spring-cloud-b-grayspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:1.0.0imagePullPolicy: Alwaysname: spring-cloud-b-grayports:- containerPort: 20002livenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30---apiVersion: apps/v1
kind: Deployment
metadata:name: spring-cloud-c-gray
spec:selector:matchLabels:app: spring-cloud-c-graytemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-clabels:app: spring-cloud-c-grayspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:1.0.0imagePullPolicy: Alwaysname: spring-cloud-c-grayports:- containerPort: 20003livenessProbe:tcpSocket:port: 20003initialDelaySeconds: 10periodSeconds: 30
部署完成之后我们引入流量并进行验证
登录 MSE 治理中心控制台[4]选择应用列表。单击应用 spring-cloud-a 应用详情菜单此时可以看到所有的流量请求都是去往 spring-cloud-a 应用未打标的版本即稳定版本。点击页面下方的 标签路由中的添加按钮为 spring-cloud-a 应用的 gray 版本设置灰度规则。发起流量调用我们通过 zuul-slb分别发起流量调用并查看灰度的情况。我们通过 spring-cloud-a 和 spring-cloud-a-gray 的日志去查看消息消费的情况。可以看到消息的灰度功能已经生效 spring-cloud-a-gray 这个环境只会消费带有 gray 标的消息spring-cloud-a 这个环境只会消费未打标的流量生产出来的消息。
在截图中我们可以看见spring-cloud-a-gray 环境输出的日志 topic:TEST_MQ, producer: Cgray [10.25.0.102] , invoke result: Agray[10.25.0.101] - Bgray[10.25.0.25] - Cgray[10.25.0.102] spring-cloud-a-gray 只会消费 Cgray 生产出来的消息而且消费消息过程中发起的 Spring Cloud 调用结果也是 Agray[10.25.0.101] - Bgray[10.25.0.25] - Cgray[10.25.0.102]即在灰度环境闭环。
而 spring-cloud-a 这个环境输出的日志为 topic:TEST_MQ,producer:C[10.25.0.157],invoke result:A[10.25.0.100] - B[10.25.0.152] - C[10.25.0.157]只会消费 C 的基线环境生产出来的消息且在这个过程中发起的 Spring Cloud 调用也是在基线环境闭环。 步骤五调整消息的标签过滤规则并进行验证
因为考虑到实际场景中spring-cloud-c 应用和 spring-cloud-a 应用的所有者可能不是同一个人不一定能够做到两者同时进行灰度发布同步的操作所以在消息的灰度中未打标环境默认的行为是消费所有消息。这样 spring-cloud-c 在进行灰度发布的时候可以不需要强制 spring-cloud-a 应用也一定要同时灰度发布且使用相同的环境标。
spring-cloud-a 在消费时候未打标环境的行为的选择权是交给 spring-cloud-a 的所有者如果需要实现未打标环境不消费 c-gray 生产出来的消息只需要在控制台进行配置即可配置之后实时生效。
调整 spring-cloud-a 未打标环境的过滤规则。比如这里我们要选择未打标环境不再消费 gray 环境生产出来的消息只需要在“未打标环境忽略的标签”里面选择 gray然后点击确定即可。调整规则之后规则是可以动态地生效不需要进行重启的操作我们直接查看 spring-cloud-a 的日志验证规则调整生效。
从这个日志中我们可以看到此时基线环境可以同时消费 gray 和 基线环境生产出来的消息而且在消费对应环境消息时产生的 Spring Cloud 调用分别路由到 gray 和 基线环境中。 操作总结
全链路消息灰度的整个过程是不需要修改任何代码和配置的。目前仅支持 RocketMQClient 版本需要在 4.5.0 之后的版本。RocketMQ Server 端需要支持 SQL92 规则过滤即开源 RocketMQ 需要配置 enablePropertyFiltertrue阿里云 RocketMQ 需要使用铂金版。开启消息灰度后MSE Agent 会修改消息消费者的 group如原来的消费 group 为 group1环境标签为 gray则 group 会被修改成 group1_gray如果使用的是阿里云 RocketMQ需要提前创建好修改后的 group。开启和关闭消息灰度后应用需要重启才能生效修改未打标环境忽略的标签功能可以动态生效不需要重启。
相关链接
[1] MSE 微服务治理专业版
微服务治理基础版升级专业版 - 微服务引擎MSE - 阿里云
[2] Kubernetes 集群
创建Kubernetes专有版集群 - 容器服务 ACK - 阿里云
[3] 容器服务控制台
阿里云登录 - 欢迎登录阿里云安全稳定的云计算服务平台
[4] MSE 治理中心控制台
阿里云登录 - 欢迎登录阿里云安全稳定的云计算服务平台
原文链接
本文为阿里云原创内容未经允许不得转载。