当前位置: 首页 > news >正文

前后端分离后灰度发布实现方式

1、什么是灰度发布

灰度发布, 也叫金丝雀发布。是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度,而我们平常所说的金丝雀部署也就是灰度发布的一种方式。

2、常见灰度发布策略

策略一:基于客户端公网ip判断是否需要走灰度环境。

策略二:基于用户判断是否走灰度环境。

3、常见实现方式

  对于前后端分离的项目,一般通过nginx 转发解决跨域问题。

3.1 只有服务需要灰度环境

当前端没有修改或者修改不影响逻辑的时候,基本只要控制服务端有灰度环境,这种情况实现如下:

   1、通过nginx+lua+redis,判断是否走灰度环境,其中redis用户存储走灰度环境用,lua在nginx 里面读取用户id,并且获取客户端请求用户id(一般通过请求头获取),通过比较判断,将在reids存储的用户转发到灰度环境网关或者服务端。(注意灰度环境的服务和正式服务注册中心不是同一个或者网络不是同一个)

2、通过服务网关辨别是否转发到灰度服务端。以SpringCloudGateway作为网关框架,nacos作为注册中、为例,具体实现方式:

定义一个灰度标记Holder

public class GrayEnvHolder {private static final ThreadLocal<EnvEnum > grayFlag = new ThreadLocal<>();public static void setGrayEnvTag(final EnvEnum tag) {grayFlag.set(tag);}public static EnvEnum getGrayEnvTag() {return grayFlag.get();}public static void remove() {grayFlag.remove();}
}

定义一个过滤器,确认是否要走灰度环境,代码如下

public class GrayGatewayBeforeFilter implements GlobalFilter, Ordered {@Autowiredprivate GrayGatewayProperties grayGatewayProperties;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {EnvEnum envEnum = EnvEnum.PROD// 当灰度开关打开时才进行请求头判断if (grayGatewayProperties.getEnabled()) {// 判断是否需要调用灰度版本if (checkGray(exchange.getRequest())) {envEnum = EnvEnum.GRAY;}}GrayEnvHolder.setGrayTag(envEnum );ServerHttpRequest newRequest = exchange.getRequest().mutate().header(GrayConstant.GRAY_HEADER, grayStatusEnum.getVal()).build();ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();return chain.filter(newExchange);}/*** 校验是否使用灰度版本*/private boolean checkGray(ServerHttpRequest request) {if ( checkGrayIPList(request)) {return true;}return false;}private boolean checkGrayIPList(ServerHttpRequest request) {// 读取走灰度环境ipList<String> grayIPList = grayGatewayProperties.getGrayIPList();if (CollectionUtils.isEmpty(grayIPList)) {return false;}String realIP = request.getHeaders().getFirst("X-Real-IP");if (realIP == null || realIP.isEmpty()) {realIP = request.getRemoteAddress().getAddress().getHostAddress();}if (realIP != null && CollectionUtils.contains(grayIPList.iterator(), realIP)) {return true;}return false;}@Overridepublic int getOrder() {// 设置过滤器的执行顺序,值越小越先执行return Ordered.HIGHEST_PRECEDENCE;}
}

然后就要通过路由重写,把不同用户转发到不同的环境。我们知道Springboot 项目负载均衡路由有Ribbon实现。它有它默认路由算法。所以我们要重新它即可。此时定义灰度环境版本变为v2:代码如下:

public abstract class AbstractGrayLoadBalancerRule extends AbstractLoadBalancerRule {@Autowiredprivate GrayVersionProperties grayVersionProperties;@Value("${spring.cloud.nacos.discovery.metadata.version}")private String metaVersion;public List<Server> getReachableServers() {ILoadBalancer lb = getLoadBalancer();if (lb == null) {return new ArrayList<>();}List<Server> reachableServers = lb.getReachableServers();return getGrayServers(reachableServers);}/*** 所有已知的服务器,可访问和不可访问,并对灰度标识进行判断*/public List<Server> getAllServers() {ILoadBalancer lb = getLoadBalancer();if (lb == null) {return new ArrayList<>();}List<Server> allServers = lb.getAllServers();return getGrayServers(allServers);}protected List<Server> getGrayServers(List<Server> servers) {List<Server> result = new ArrayList<>();if (servers == null) {return result;}String currentVersion = metaVersion;EnvEnum envEnum = GrayFlagRequestHolder.getGrayTag();if (envEnum != null) {switch (envEnum ) {case PROD:currentVersion = grayVersionProperties.getProdVersion();break;case GRAY:currentVersion = grayVersionProperties.getGrayVersion();break;}}for (Server server : servers) {NacosServer nacosServer = (NacosServer) server;Map<String, String> metadata = nacosServer.getMetadata();String version = metadata.get("version");// 判断服务metadata下的version是否于设置的请求版本一致// 注意灰度环境和生产正式环境接口版本不一样if (version != null && version.equals(currentVersion)) {result.add(server);}}return result;}
}

网关转发到到灰度环境要移除此线程holder,因此要定义后置拦截器。代码省略。网关转发后就到应用存面,考虑到微服务之间调用,因此要实现灰度标记的传递,通常是通过header传递。

public class GrayFeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {// 如果灰度标记存在,将灰度标记通过HttpHeader传递下去ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String envEnum = request.getHeader("Gray");if (envEnum != null ) {template.header(envEnum );}}
}

 当然每个微服务都要重新路由。参数上方的代码即可。方式二灰度环境和正式环境可以部署在同一个网络已经同一个nacos(同一个空间)

3.2 前端和服务端都需要灰度环境

     当前端页面改动也很大时候,或者由于业务需要或者测试需要也要将前端发布灰度环境。首先前端需要打一个灰度环境包

  实现方式如下:

      1 、实现方式 可以参照3.1中方式1,只需要将灰度的前端放指定目录,修改nginx配置即可。

此时服务转发可以直接修改nginx 到网关和微服务转发配置,也可以参照3.1中方式2实现。建议修改nginx配置,这种方式比较简洁、改动比较少

     

相关文章:

  • iOS Facebook SDK 安装
  • 针对ARM64嵌入式系统的Linux内核参数优化
  • vlan三层交换技术--交换机--(自作)
  • 测试测量-DMM直流精度
  • 我的常见问题记录
  • 学习C++第二天
  • Springboot微服务整合缓存的时候报循环依赖的错误 两种解决方案
  • 深入理解go语言反射机制
  • 电压互感器在线监测的原理
  • AI 大模型企业应用实战(10)-LLMs和Chat Models
  • AI大模型企业应用实战(14)-langchain的Embedding
  • Qt异常处理
  • 软件测试过程中用接口怎么将web系统的多页数据展示在1页
  • 罗盘时钟lua迷你世界
  • Parallels Desktop 19 for mac破解版安装激活使用指南
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • javascript从右向左截取指定位数字符的3种方法
  • MySQL数据库运维之数据恢复
  • node学习系列之简单文件上传
  • Python爬虫--- 1.3 BS4库的解析器
  • 记一次用 NodeJs 实现模拟登录的思路
  • 利用DataURL技术在网页上显示图片
  • 网络应用优化——时延与带宽
  • 微信小程序--------语音识别(前端自己也能玩)
  • 一个SAP顾问在美国的这些年
  • 智能合约Solidity教程-事件和日志(一)
  • Nginx实现动静分离
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (20)docke容器
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (4)STL算法之比较
  • (LeetCode) T14. Longest Common Prefix
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (PySpark)RDD实验实战——求商品销量排行
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (六)Hibernate的二级缓存
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • .NET CORE Aws S3 使用
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET 直连SAP HANA数据库
  • .NET中使用Protobuffer 实现序列化和反序列化
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .project文件
  • ;号自动换行
  • @WebServiceClient注解,wsdlLocation 可配置
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器
  • [12] 使用 CUDA 进行图像处理
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [ACP云计算]易混淆知识点(考题总结)
  • [AIGC] Kong:一个强大的 API 网关和服务平台