全链路灰度之 RocketMQ 灰度
简介:本文将以上次介绍过的《如何用 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-c,spring-cloud-c 在收到请求后,会生产一个消息,并返回自己的环境标签和 ip。这些生产出来的消息会由 spring-cloud-a 应用消费,spring-cloud-a 应用在消费消息的时候,会通过 spring cloud 去调用 B,B 进而通过 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 Server apiVersion: apps/v1
kind: Deployment
metadata:
name: nacos-server
spec:
selector:
matchLabels:
app: nacos-server
template:
metadata:
annotations:
labels:
app: nacos-server
spec:
containers:
- env:
- name: MODE
value: "standalone"
image: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latest
imagePullPolicy: IfNotPresent
name: nacos-server
ports:
- containerPort: 8848 ---
apiVersion: v1
kind: Service
metadata:
name: nacos-server
spec:
type: ClusterIP
selector:
app: nacos-server
ports:
- name: http
port: 8848
targetPort: 8848 # 部署业务应用
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-zuul
spec:
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: enable.mq.invoke
value: 'true'
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.0
imagePullPolicy: Always
name: spring-cloud-zuul
ports:
- containerPort: 20000 ---
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small
service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet
name: zuul-slb
spec:
ports:
- port: 80
protocol: TCP
targetPort: 20000
selector:
app: spring-cloud-zuul
type: LoadBalancer
status:
loadBalancer: {} ---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-a
spec:
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30 ---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-b
spec:
selector:
matchLabels:
app: spring-cloud-b
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 20002
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30 ---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c
spec:
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 20003
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 30
--- apiVersion: apps/v1
kind: Deployment
metadata:
name: rockectmq-broker
spec:
selector:
matchLabels:
app: rockectmq-broker
template:
metadata:
labels:
app: rockectmq-broker
spec:
containers:
- command:
- sh
- mqbroker
- '-n'
- 'mqnamesrv:9876'
- '-c /home/rocketmq/rocketmq-4.5.0/conf/broker.conf'
env:
- name: ROCKETMQ_HOME
value: /home/rocketmq/rocketmq-4.5.0
image: registry.cn-shanghai.aliyuncs.com/yizhan/rocketmq:4.5.0
imagePullPolicy: Always
name: rockectmq-broker
ports:
- containerPort: 9876
protocol: TCP
- containerPort: 10911
protocol: TCP
- containerPort: 10912
protocol: TCP
- containerPort: 10909 --- apiVersion: apps/v1
kind: Deployment
metadata:
name: rocketmq-name-server
spec:
selector:
matchLabels:
app: rocketmq-name-server
template:
metadata:
labels:
app: rocketmq-name-server
spec:
containers:
- command:
- sh
- mqnamesrv
env:
- name: ROCKETMQ_HOME
value: /home/rocketmq/rocketmq-4.5.0
image: registry.cn-shanghai.aliyuncs.com/yizhan/rocketmq:4.5.0
imagePullPolicy: Always
name: rocketmq-name-server
ports:
- containerPort: 9876
protocol: TCP
- containerPort: 10911
protocol: TCP
- containerPort: 10912
protocol: TCP
- containerPort: 10909
protocol: TCP --- apiVersion: v1
kind: Service
metadata:
name: mqnamesrv
spec:
type: ClusterIP
selector:
app: rocketmq-name-server
ports:
- name: mqnamesrv-9876-9876
port: 9876
targetPort: 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 47h NAME 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 中配置 enablePropertyFilter=true)。
- 默认情况下,未打标节点将消费所有环境的消息,若需要指定 未打标环节点 不消费 某个标签环境生产出来的消息,请配置“未打标环境忽略的标签”,修改此配置后动态生效,无需重启应用。
步骤四:重启节点,部署新版本应用,并引入流量进行验证
首先,因为开启和关闭应用的消息灰度功能后都需要重启节点才能生效,所以首先我们需要重启一下 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-gray
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a-gray
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-a-gray
ports:
- containerPort: 20001
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-b-gray
spec:
selector:
matchLabels:
app: spring-cloud-b-gray
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-b
labels:
app: spring-cloud-b-gray
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-b-gray
ports:
- containerPort: 20002
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30 --- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c-gray
spec:
selector:
matchLabels:
app: spring-cloud-c-gray
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c-gray
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:1.0.0
imagePullPolicy: Always
name: spring-cloud-c-gray
ports:
- containerPort: 20003
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 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 和 基线环境中。
操作总结
- 全链路消息灰度的整个过程是不需要修改任何代码和配置的。
- 目前仅支持 RocketMQ,Client 版本需要在 4.5.0 之后的版本。RocketMQ Server 端需要支持 SQL92 规则过滤,即开源 RocketMQ 需要配置 enablePropertyFilter=true,阿里云 RocketMQ 需要使用铂金版。
- 开启消息灰度后,MSE Agent 会修改消息消费者的 group,如原来的消费 group 为 group1,环境标签为 gray,则 group 会被修改成 group1_gray,如果使用的是阿里云 RocketMQ,需要提前创建好修改后的 group。
- 开启和关闭消息灰度后,应用需要重启才能生效;修改未打标环境忽略的标签功能可以动态生效,不需要重启。
相关链接
[1] MSE 微服务治理专业版:
微服务治理基础版升级专业版 - 微服务引擎MSE - 阿里云
[2] Kubernetes 集群:
创建Kubernetes专有版集群 - 容器服务 ACK - 阿里云
[3] 容器服务控制台:
[4] MSE 治理中心控制台
本文为阿里云原创内容,未经允许不得转载。
全链路灰度之 RocketMQ 灰度的更多相关文章
- 基于 Istio 的全链路灰度方案探索和实践
作者|曾宇星(宇曾) 审核&校对:曾宇星(宇曾) 编辑&排版:雯燕 背景 微服务软件架构下,业务新功能上线前搭建完整的一套测试系统进行验证是相当费人费时的事,随着所拆分出微服务数量的不 ...
- Opentracing + Uber Jaeger 全链路灰度调用链,Nepxion Discovery
当网关和服务在实施全链路分布式灰度发布和路由时候,我们需要一款追踪系统来监控网关和服务走的是哪个灰度组,哪个灰度版本,哪个灰度区域,甚至监控从Http Header头部全程传递的灰度规则和路由策略.这 ...
- 基于Opentracing+Jaeger全链路灰度调用链
当网关和服务在实施全链路分布式灰度发布和路由时候,我们需要一款追踪系统来监控网关和服务走的是哪个灰度组,哪个灰度版本,哪个灰度区域,甚至监控从Http Header头部全程传递的灰度规则和路由策略.这 ...
- 全链路压测平台(Quake)在美团中的实践
背景 在美团的价值观中,以“客户为中心”被放在一个非常重要的位置,所以我们对服务出现故障越来越不能容忍.特别是目前公司业务正在高速增长阶段,每一次故障对公司来说都是一笔非常不小的损失.而整个IT基础设 ...
- 灰度发布:灰度很简单,发布很复杂&灰度发布(灰度法则)的6点认识
什么是灰度发布,其要点有哪些? 最近跟几个聊的来的同行来了一次说聚就聚的晚餐,聊了一下最近的工作情况如何以及未来规划等等,酒足饭饱后我们聊了一个话题“灰度发布”. 因为笔者所负责的产品还没有达到他们产 ...
- skywalking与pinpoint全链路追踪方案对比
由于公司目前有200多微服务,微服务之间的调用关系错综复杂,调用关系人工维护基本不可能实现,需要调研一套全链路追踪方案,初步调研之后选取了skywalking和pinpoint进行对比; 选取skyw ...
- 京东全链路压测军演系统(ForceBot)架构解密
摘要:全链路压测是应对电商大促容量规划最有效的手段,如何有效进行容量规划是其中的架构关键问题.京东在全链路压测方面做过多年尝试,本文转载京东商城基础平台技术专家文章,介绍其最新的自动化压测 Force ...
- 全链路追踪traceId,ThreadLocal与ExecutorService
关于全链路追踪traceId遇到线程池的问题,做过架构的估计都遇到过,现在以写个demo,总体思想就是获取父线程traceId,给子线程,子线程用完移除掉. mac上的chrome时不时崩溃,写了一大 ...
- C#编写Windows服务程序 (服务端),client使用 消息队列 实现淘宝 订单全链路效果
需求: 针对 淘宝提出的 订单全链路 产品接入 .http://open.taobao.com/doc/detail.htm?id=102423&qq-pf-to=pcqq.group oms ...
- 全链路实践Spring Cloud 微服务架构
Spring Cloud 微服务架构全链路实践Spring Cloud 微服务架构全链路实践 阅读目录: 网关请求流程 Eureka 服务治理 Config 配置中心 Hystrix 监控 服务调用链 ...
随机推荐
- 【转】客户端软件GUI开发技术漫谈:原生与跨平台解决方案分析
原生开发应用开发 Microsoft阵营的 Winform WinForm是·Net开发平台中对Windows Form的一种称谓. 如果你想深入的美化UI,需要耗费很大的力气,对于目前主流的CSS样 ...
- 移植openssh-7.5p1(包括openssl-1.0.2l、zlib-1.2.11)到HISI3520d(部署篇)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 大年学习linux(第一节)
Linux学习笔记 一.常用命令 终端快键键: Ctrl+a/home 切换到命令行开始 Ctrl+e/end 切换到命令行末尾 Ctrl+i 清除屏幕内容,效果等同于clear Ctrl + u 清 ...
- 直播预约 | 邀您共同探讨“云XR技术如何改变元宇宙的虚拟体验”
随着数字化时代的到来,元宇宙成为了人们关注的焦点.它是一个虚拟的世界,融合了现实与虚拟的元素,让人们可以以全新的方式进行交互.创作和体验. 云XR技术是元宇宙建设的重要支撑技术之一,元宇宙需要具备高度 ...
- 工作记录:8个有用的JS技巧
这里给大家分享我最近学习到的8个有用的js小技巧,废话不多说,我们上代码 1. 确保数组值 使用 grid ,需要重新创建原始数据,并且每行的列长度可能不匹配, 为了确保不匹配行之间的长度相等,可以使 ...
- 记录--uni-app在不同平台下拨打电话
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 场景 在App中拨打电话是一个比较常见的应用场景,但是我们通过搜索文章,发现,大部分的博文都是uni-app官网的copy, copy u ...
- 提升团队协作效率:欧奥PicHome打造无缝资料共享平台
1. 引言 在快节奏的工作环境中,团队成员需要快速访问和共享信息.有效的资料共享不仅提高工作效率,还能促进团队协作和创新.然而,许多团队仍在使用传统的文件共享方法,这些方法往往效率低下,难以满足现代工 ...
- KingbaseES 行级安全策略介绍
本文详细介绍了KingbaseES中通过CREATE POLICY为一个表定义一条行级安全性策略.注意为了应用已被创建的策略,在表上必须启用行级安全性. 策略名称是针对每个表的.因此,一个策略名称可以 ...
- KingbaseES V8R6备份恢复案例之---sys_restore实现schema转换
**案例说明:** sys_restore用于sys_dump备份的数据恢复,在实际的应用中有需求,将从sys_dump备份对象从原schema中转换到到另外的schema,sys_restore支持 ...
- KingbaseES sys_bulkload数据加载工具错误处理
一.关于sys_bulkload数据加载工具 sys_bulkload是KingbaseES提供的快速加载数据的命令行工具.用户使用sys_bulkload工具能够把一定格式的文本数据简单.快速的加载 ...