前言
微服务架构中的灰度发布(也称为金丝雀发布或渐进式发布)是一种在不影响现有用户的情况下,逐步将新版本的服务部署到生产环境的策略。通过灰度发布,你可以先将新版本的服务暴露给一小部分用户或特定的流量,观察其表现,确保没有问题后再逐步扩大流量,最终完全替换旧版本。
注: 该灰度方案的实现主要基于java 去实现
灰度发布的优点
- 降低风险:通过只对一部分用户或流量进行更新,可以减少新版本引入的问题对所有用户的影响。
- 快速回滚:如果新版本出现问题,可以迅速将流量切换回旧版本,避免影响更多用户。
- 渐进式验证:可以在小范围内验证新版本的功能和性能,确保其稳定性和兼容性。
- 用户体验优化:可以通过灰度发布收集用户反馈,逐步优化新功能,而不必一次性全面推广。
- 避免熬夜发版
设计概要
系统架构图
流量控制
客户端
对于请求流量识别控制,可以据实际需求,设计,下面列举,几种常用的
- 用户
- 设备ID
- 客户端版本
- 客户端标签
服务端
流量管理服务端,主要作用,灰度信息管理及控制:
- 管理: 用户、 设备ID、 客户端版本,客户端标签,等维度信息;
- 灰度信息推送到网关: 让网关依据这些信息,请求识别为正常流量还上灰度流量,
如果正常流量,将路由到正常实例;如果是灰度流量,将路由到灰度实例;
注:为了简化设计同时满足核心需求,不做过度设计,实现仅给流量打上灰度标签或无(正常流量)
路由路径
- 网关->ribbon->cloud服务->ribbon->cloud服务
- 网关->ribbon->cloud服务->thread–>ribbon->dubbo服务
- 网关->ribbon->cloud服务->mq服务->cloud服务
- 网关->dubbo->dubbo服务->thread->dubbo服务
- 网关->dubbo->dubbo服务->mq服务->dubbo服务
上面大概列举基本请求,所可能经过的路径,要实现灰度路由,经过这些路径的组件,必须实现灰度标签
的传递,及据灰度标签选择路由
应用客户端实现
因为需要对应用实例状态的控制以及服务实例之间的灰度标签传递和路由,所以需要修改相关客户端代码的实现。
- sdk 方式
如果采用该方法可能面临的问题:
1.业务应用推广难大,需要对所有应用依赖升级打包
2.跨线程标签续传可能需求修改来务业务代码,代价太大了
3 消息队列收发,可能要调整业务代 - agent 方式
该方式可以很好解决sdk方式的三个问题,但开发会复杂些; - 综合分析,采用 agent 方式更为合适些
核心组件分析
1.网关
网关作为后端流量的统一入囗,在灰度布实现中,充当着什么重要的角色;
- 担任着灰度信息管理,
- 入口流量的灰度识别
- 请求路由(确认是路由到正常服务实例或是灰度实例)
2. spring-cloud
如果微服务实现的是spring-cloud,灰度路由的控制需要实现以下几点
- eureka client 自动生成实例id作为元数据,上报到注册中心,用作实例与管理标识管理
- 灰度标签的续传,如a服务调用b服务,把标签通过http请求头传递到b服务
- 拦截feign调用或 RestTemplate 把灰度请求添加到http 请求头里
- ribbon 的rule 拦截,依赖灰度标签做路由选择
3. dubbo
如果微服务实现的是dubbo,处理跟spring-cloud类似,灰度路由的控制需要实现以下几点
- 灰度标签的续传,如a服务调用b服务,把标签通过rpc attachment续给续传
- 拦截dubbo 路由接口,依赖灰度标签做路由选择
4. nocas
如果注册中心使用的是nacos,同步也要自动上报实例id,到nacos注册中心
5. thread
在服务路由选择时,需要依赖灰度标签,所以需要把灰度标签由一引服务传递到另一个服务,或一个线程传到另一个线程;
像经过spring-cloud或dubbo这些框架上面已实现跨服务标签续传,但是如果业务代码内出现跨线程操作后,则会出现标签断传;
处理该问题可以分别对以下接口或类进行,标签续传增强处理:
- 拦截Runnable或Callable,接口增强实现标签续传;
- 拦截ThreadPoolExecutor, 但是当业务使用Callable或Runnable 时,使用的是lambda表达式时,
可以通过拦截ThreadPoolExecutor,增强实现标签续传
6. message queue
一般现在的后端服务,难免会用到消息队列;如果用到自然也要对消息队列,消费路由处理;
但是消息的消费无法像微服务之间调用,可据路由规则选择提供方;
既然无法像服务之间调用处理去理路由,只有另求其他办法,据消息中间件具体的特性,也可以实现同样的消息
1.kakfa,rocketmq 可以把topic,分成正常消费组和灰度消费组,各自只接口符合自身状态的消息,其它状成的消息丢掉
2.rabbit 可以分正常virtualhost和灰度virthualHost,收发消息
… 未完,后续介绍具体的实现
最后,给大家安利一款mysql监控软件: 安装方便,消耗低,可视化,傻瓜式操作,可以监控慢日志详情、cpu、内存、连接数、tps 等信息
体验演示
下载地址