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

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配置,这种方式比较简洁、改动比较少

     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/34113.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 教程

MySQL 教程 目录 简介安装 MySQL WindowsmacOSLinux 连接 MySQL 命令行客户端图形化工具 基础操作 创建数据库删除数据库选择数据库 表的操作 创建表删除表插入数据查询数据更新数据删除数据 高级操作 索引视图存储过程触发器 用户管理 创建用户授权删除用户 备份与恢复 备份…

Vatee万腾平台:技术引领,智能先行

在科技日新月异的今天&#xff0c;智能技术正以前所未有的速度改变着我们的世界。在众多科技平台中&#xff0c;Vatee万腾平台凭借其卓越的技术实力和前瞻性的战略眼光&#xff0c;成为了智能技术领域的佼佼者。它始终坚持“技术引领&#xff0c;智能先行”的理念&#xff0c;推…

如何在 Odoo 17 库存模块中进行质量控制

质量控制是确保制造产品质量符合最终要求的关键步骤。有效的质量控制能够提高客户满意度。在生产过程中,质量检测可以在多个环节进行,以便及时发现并解决问题。不同的行业采用的质量控制技术可能有所不同。 在商业尤其是制造业中,保证产品质量至关重要。一个产品需要经过多次…

【科技前沿】电子设计新贵SmartEDA:为何它引领行业风潮?

在当今这个电子科技日新月异的时代&#xff0c;电子设计工具如同设计师的魔法棒&#xff0c;不断推动着产品创新的速度。而近期&#xff0c;一款名为SmartEDA的电子国产设计仿真软件异军突起&#xff0c;成为了行业内的新宠。那么&#xff0c;SmartEDA究竟有何过人之处&#xf…

Adaptive Server Connection Failed on Windows

最近在使用pymssql &#xff08;版本2.3.0&#xff09;连接SQL Server2012遇到如下问题&#xff1a; pymssql._mssql.MSSQLDatabaseException: (20002, bDB-Lib error message 20002, severity 9:\nAdaptive Server connection failed (localhost)\nDB-Lib error message 2000…

LeetCode:503. 下一个更大元素 II(Java 单调栈)

目录 503. 下一个更大元素 II 题目描述&#xff1a; 实现代码与解析&#xff1a; 单调栈 原理思路&#xff1a; 503. 下一个更大元素 II 题目描述&#xff1a; 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&…

分布式锁实现方案-基于Redis实现的分布式锁

目录 一、基于Lua看门狗实现 1.1 缓存实体 1.2 延迟队列存储实体 1.3 分布式锁RedisDistributedLockWithDog 1.4 看门狗线程续期 1.5 测试类 1.6 测试结果 1.7 总结 二、RedLock分布式锁 2.1 Redlock分布式锁简介 2.2 RedLock测试例子 2.3 RedLock 加锁核心源码分析…

2009年-2022年 地级市-环境污染处罚数据

环境污染处罚数据是环境保护领域中重要的信息资源&#xff0c;它记录了因违反环保法律法规而受到行政处罚或法律制裁的具体情况。这些数据对于提高公众的环保意识、促进企业采取环保措施以及推动环境治理具有重要作用。 数据内容概述 违法行为的主体&#xff1a;即受到处罚的…

私域引流的艺术:高效策略解锁流量密码

在数字化营销的浪潮中&#xff0c;私域流量以其高黏性和低成本的优势成为品牌和企业竞相追逐的宝藏。然而&#xff0c;如何有效引流至私域&#xff0c;却成了摆在每个运营者面前的难题。今天&#xff0c;我们将一起探索那些值得采用的私域引流方法&#xff0c;帮助你解锁流量的…

虚拟机有哪些写一篇文章

虚拟机技术作为现代计算环境中的重要组成部分&#xff0c;极大地丰富了我们对资源管理和系统部署的理解与实践。本文将深入探讨虚拟机的定义、工作原理、应用场景、优势、主要技术以及未来发展趋势&#xff0c;帮助读者全方位地理解虚拟机这一强大技术。 虚拟机概述虚拟机&…

利用cuda的cublas库,编写复数矩阵乘的代码

学习内容&#xff1a; 利用cuda的cublas库&#xff0c;编写复数矩阵乘的代码 学习产出&#xff1a; 编写代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> #include <cuda_runtime.h> #include <cublas_v2.h> #include <random>…

【力扣】从前序与中序遍历序列构造二叉树

&#x1f525;博客主页&#xff1a; 我要成为C领域大神 &#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于分享知识&#xff0c;欢迎大家共同学习和交流。 给定两个整数数…

如何解决app广告填充率低、广告填充异常,提升广告变现收益?

APP广告变现有助于开发者获得持续的收益来源&#xff0c;由于广告链路的封闭性和复杂化&#xff0c;一旦出现请求配置参数错误、返回广告源信息缺失、素材被拦截等异常&#xff0c;大部分开发者很难及时查清异常情况&#xff0c;导致广告填充率不理想&#xff0c;甚至填充率常常…

【云服务-2】云服务器

弹性云服务器和服务器组的区别&#xff1f; 弹性云服务器和服务器组在云计算环境中有以下区别: 弹性云服务器(Elastic Cloud Server, ECS): 弹性云服务器是独立的虚拟机实例,可以独立启动、停止和管理。 弹性云服务器作为一个独立的计算资源运行,可以根据业务需求进行灵活扩展…

【Linux】linux系统VIM简介_使用

1、简介 1.1定义 VIM&#xff08;Vi IMproved&#xff09;是 Vi 编辑器的增强版本&#xff0c;提供了更多的功能和改进的用户界面。它被广泛认为是程序员的编辑器首选之一&#xff0c;特别适用于代码编辑和文本处理。VIM 拥有多种模式&#xff0c;每种模式都有其特定的功能和…

ImportError: No module named createrepo

我在用createrepo命令创建本地源时&#xff0c;出现如下&#xff1a; ImportError: No module named createrepo原因估计就是之前升级python2.6为2.7时导致&#xff08;系统为centos7&#xff09;&#xff0c;看网上很多说&#xff0c; 修改/usr/share/createrepo/genpkgmeta…

大咖共话|智领未来,数字化革新生命健康产业

在数字化浪潮席卷全球的今天&#xff0c;生命健康产业正迎来前所未有的发展机遇。6月20日&#xff0c;“第三届滨海中关村协同创新发展交流会”在北京隆重举办&#xff0c;唯迈医疗与业界大咖齐聚一堂&#xff0c;在“数字化赋能驱动生命健康产业发展”圆桌论坛上&#xff0c;共…

【PostgreSQL】AUTO_EXPLAIN - 慢速查询的日志执行计划

本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 一、介绍 在本文中&#xff0c;我们将了解 PostgreSQL AUTO_EXPLAIN功能的工作原理&#xff0c;以及为什么应该使用它来收集在生产系统…

(1985-2022年)各省、地级市数字经济专利数据 整理

数字经济专利数量是衡量一个国家或地区在数字经济领域创新能力和技术发展水平的重要指标。这些专利通常与数字技术、互联网、大数据分析、云计算、人工智能&#xff08;AI&#xff09;、区块链、物联网&#xff08;IoT&#xff09;等创新成果相关。数字经济专利的增长不仅反映了…

[JS]函数

介绍 函数就是用来执行特点任务的代码块, 目的是实现代码复用, 提高开发效率 使用 1.0函数的声明 function 函数名 () {//函数体 } 2.0函数的调用 3.0命名规范 和变量命名规则基本一致尽量小驼峰式命名前缀应该为动词 传参 函数的参数可以极大提高函数的灵活性 1.0参数…