作者:泮圣伟(十眠)
概要
全链路灰度是微服务最中心的功用之一,也一直是云上客户在微服务化深入过程中必须具有的功用。全链路灰度由于触及到的技能、场景很多,假如云上企业逐个自己完结,需求花费大量人力本钱对其进行扩展与运维。
触及到的技能范畴
-
RPC: 微服务之间的路由
-
- Java 体系触及 Spring Cloud,Apache Dubbo 干流微服务结构,多语言触及 Service Mesh
-
- 端云互联场景,线上流量 DEBUG。本地通过跳板机将本地服务注册到注册中心,期望线上流量满足路由规矩后路由到本地服务关于的实例上再进行 DEBUG,不满足路由规矩的流量路由到线上实例
-
MQ
-
- 全链路压测场景下,压测流量发送音讯到影子 Topic,压测流量只订阅影子 Topic
-
- 流量阻隔/全链路灰度场景下,运用相同 Topic,线上流量订阅线上音讯,阻隔流量只订阅灰度音讯
-
Database
-
- 全链路压测场景下,压测流量数据落库到到影子表上
-
- 高可用切流的场景下,制止数据库操作;单元化下,流量没有单元标,制止数据库操作
-
Redis
-
- 全链路压测场景下,压测流量缓存落库到到影子 KEY 上
-
- 高可用切流的场景下,制止缓存操作;单元化下,流量没有单元标,制止缓存操作
-
分布式使命调度
-
- 关于使命调度,灰度环境提交的使命,被调度到灰度环境的机器上执行
-
前端
-
- 不同客户看到的页面信息不一致
-
可观测性
-
- 通过可观测性监控流量走向,检查流量逃逸状况
MSE 全链路灰度解决方案
现在 MSE 服务管理专业版提供了完好的产品化的全链路灰度解决方案,掩盖 RPC、MQ、可观测性等绝大多数场景。只要您的架构是依据 Spring Cloud 或许 Dubbo 结构,您的运用无需晋级,无需一行代码改动,即可玩转企业级全链路灰度功用。
- 全链路阻隔流量泳道
1) 通过设置流量规矩对所需流量进行’染色’,’染色’流量会路由到灰度机器。
2) 灰度流量携带灰度标往下流传递,构成灰度专属环境流量泳道,无灰度环境运用会默许挑选未打标的基线环境。
- 端到端的安稳基线环境
未打标的运用归于基线安稳版别的运用,即安稳的线上环境。当咱们将发布对应的灰度版别代码,然后能够装备规矩定向引入特定的线上流量,操控灰度代码的风险。
- 流量一键动态切流
流量规矩定制后,可依据需求进行一键停启,增修正查,实时收效。灰度引流更快捷。
- 可观测才能
具有泳道级别的单运用可观测才能
一起具有全链路运用的可观测才能,能够从大局视角观察流量是否存在逃逸状况。灰没灰到,一目了然。
- 低本钱接入,依据 Java Agent 技能完结无需修正一行事务代码
MSE 微服务管理才能依据 Java Agent 字节码增强的技能完结,无缝支撑市面上近5年的一切 Spring Cloud 和 Dubbo 的版别,用户不用改一行代码就能够运用,不需求改动事务的现有架构,随时可上可下,没有绑定。只需敞开 MSE 微服务管理专业版,在线装备,实时收效。
- 具有无损上下线才能,使得发布更加丝滑
运用敞开 MSE 微服务管理后就具有无损上下线才能,大流量下的发布、回滚、扩容、缩容等场景,均能确保流量无损。
如何运用 MSE 全链路灰度
接下来将演示全链路灰度的才能,咱们运用运用的架构由 Ingress-nginx 以及后端的微服务架构(Spring Cloud)来组成,后端调用链路有3跳,购物车(a),交易中心(b),库存中心(c),客户端通过 客户端或许是 H5 页面来拜访后端服务,他们通过 Nacos 注册中心做服务发现。
准备工作
注册 MSE 微服务管理专业版
登录 MSE 管理中心操控台,假如您尚未注册 MSE 微服务管理,请依据提示注册专业版。假如您已经注册了 MSE 微服务管理基础版,请依据概览页中右侧的提示,晋级到 专业版。
装置 Ingress-nginx 组件
- 登录容器服务操控台 [1] 。
- 在左边导航栏挑选商场 > 运用目录。
- 在运用目录页面搜索框中输入 ack-ingress-nginx,单击图标,然后单击组件。
- 在概况页面挑选组件的命名空间为 kube-system,然后单击创立。装置完结后,在命名空间 kube-system 中呈现 ack-ingress-nginx-default-controller 运用,表示装置成功。
布置 Demo 运用程序
将下面的文件保存到 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 规矩
装备入口的 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
点击文末“此处”,了解更多概况~