项目迭代中新老逻辑切换入口

前言

​ 日常我们在项目开发中经常会进行项目迭代,比如说开发初期设定的代码逻辑根据功能需求迭代逐渐发现越来越难用,或者改动是对整体较大时,往往会进行专项处理,对这个逻辑进行改造。

​ 那么就会涉及到原先被调用方切换接口等问题,这种情况我们为了让外部接口无感知,都是采用内部切流的方式进行外部无感知的。

那么我们来构造一个场景来看看如何进行切流和代码改造。

正文

我们有几个逻辑需要改造的接口

@Service
public class ARepository {@Resourceprivate AMapper aMapper;public AEntity query(long id){//原有的接口逻辑处理}
}@Service
public class BRepository {@Resourceprivate BMapper bMapper;public List<BEntity> query(long id){//原有的接口逻辑处理}
}

思路

  1. 以接口的维度来控制每一个接口是否要进行切流
  2. 新建一个同级别的新接口实现改造后的逻辑,避免新老逻辑在同一个文件里混杂
  3. 以配置的形式来判断是否需要切换,若出现问题可单独进行回溯

实现方式

apollo

我们创建一个可以随时改动的配置,我这里使用 apollo 进行配置以便随时改动和发布生效:

  1. 每一个 Repository 有唯一一个 key 值,然后去 value 里面找方法 key。

  2. 布尔值 false 表示走原逻辑、true 表示走改造后的逻辑。

{"ARepository":{"query":false},"BRepository":{"query":false}
}

新逻辑

@Service
public class NewARepository {@Resourceprivate AMapper aMapper;public AEntity query(long id){//新的接口逻辑处理}
}@Service
public class NewBRepository {@Resourceprivate BMapper bMapper;public List<BEntity> query(long id){//新的接口逻辑处理}
}

切流控制

创建一个切流控制类,使用上面的 apollo 来判断是否需要执行新逻辑并返回。

我们构造一个泛型类,统一注入新逻辑类,在调用 switchHandler 是传入新逻辑函数,通过 apollo 判断是否需要执行

@Slf4j
@Getter
@Component
public class MapperSwitchHandler {@Resourceprivate NewARepository newARepository;@Resourceprivate NewBRepository newARepository;//lombok忽略此属性,不生成 get 方法@Getter(AccessLevel.NONE)//获取 apollo 配置信息@ApolloJsonValue(namespace = "namespace", config = "config", key = "key")private JSONObject mapperSwitch;/*** @Author: zhou* @Description: 根据传入参数获取 apollo 配置的 boolean 值* @Date: 2024/5/27 11:38* @Param: className apollo 中类名--一级* @Param: methodName apollo 中方法名--二级* @return: boolean*/private boolean switchResult(String className, String methodName) {if (mapperSwitch == null) {return false;}return Optional.ofNullable(mapperSwitch.getJSONObject(className)).map(item -> item.getBoolean(methodName)).orElse(false);}/*** @Author: zhou* @Description: 根据 apollo 配置的 boolean 值来判断是否执行传入的 action 函数,并获取结果* @Date: 2024/5/27 11:36* @Param: className apollo 中类名* @Param: methodName apollo 中方法名* @Param: action 待执行函数* @return: MapperSwitchHandler.Result<T>*/public <T> Result<T> switchHandler(String className, String methodName, Supplier action) {Result<T> result = new Result<>();boolean flag = switchResult(className, methodName);log.info("className:{}, methodName:{}, mapper switch : {}", className, methodName, flag);result.setFlag(flag);if (result.isFlag()) {result.setData((T) action.get());log.info("new logic result :{}", JSONObject.toJSONString(result.getData()));} else {log.info("old logic start...");}return result;}@Slf4j@Datapublic static class Result<T> {/*** 逻辑标识*/private boolean flag;/*** 获取的结果*/private T data;}
}

这样我们就实现好了新逻辑的控制和改造,现在需要对原逻辑进行改造判断。

老逻辑改造

@Service
public class ARepository {@Resourceprivate AMapper aMapper;//注入开关@Resourceprivate MapperSwitchHandler mapperSwitchHandler;public AEntity query(long id){MapperSwitchHandler.Result<AEntity> result = mapperSwitchHandler.switchHandler("ARepository","query",() -> mapperSwitchHandler.getNewARepository().query(id));// flag 判断是否走新 sql ,true 标识走新 sql,直接返回;false 标识走老逻辑if (result.isFlag()) {return result.getData();}//原有的接口逻辑处理}
}@Service
public class BRepository {@Resourceprivate BMapper bMapper;//注入开关@Resourceprivate MapperSwitchHandler mapperSwitchHandler;public List<BEntity> query(long id){MapperSwitchHandler.Result<List<BEntity>> result = mapperSwitchHandler.switchHandler("BRepository","query",() -> mapperSwitchHandler.getNewBRepository().query(id));// flag 判断是否走新 sql ,true 标识走新 sql,直接返回;false 标识走老逻辑if (result.isFlag()) {return result.getData();}//原有的接口逻辑处理}
}

这样我们就实现了通过 apollo 配置来灵活的判断每一个接口层面的逻辑控制。待灰度完成或者新逻辑全部正确的时候我们有两种方式来进行代码清理:

  • 完全删掉老的类文件,原调用方只需要重新引用新的接口类
  • 只删除老逻辑,老接口的入口调用新逻辑即可。

尾言

​ 本文介绍了在进行代码改造进行逻辑切流失的逻辑操作,通过 apollo 配置来实时动态的判断各个接口的控制效果,通过统一的处理类避免了每一个需要改造的代码都需要引用新的逻辑类和开关配置。总体来说是一个比较不错的方案,第一次实现此场景,如果更好的建议可以交流一下。

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

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

相关文章

成功解决“ModuleNotFoundError: No module named ‘tensorflow_datasets‘”错误的全面指南

成功解决“ModuleNotFoundError: No module named ‘tensorflow_datasets’”错误的全面指南 在Python编程和深度学习项目中&#xff0c;tensorflow_datasets&#xff08;通常简称为tfds&#xff09;是一个非常重要的库&#xff0c;它提供了大量现成的数据集&#xff0c;方便…

终于来啦!Stable Diffusion 3将在6月12日正式开源

6月3日晚&#xff0c;著名开源大模型平台Stability AI的联合首席执行官Christian Laforte&#xff0c;在AMD的产品发布会上宣布&#xff0c;文生图模型 Stable Diffusion 3将于6月12日在Hugging Face开源权重。 本次开源的是Stable Diffusion 3的Medium模型&#xff0c;有20亿…

武汉盛势启创科技携手三品软件 EDM系统助力企业图文档数字化

客户简介 武汉盛势启创科技有限公司&#xff08;以下简称“盛世启创”&#xff09;是一家专注于新能源汽车零部件领域的科技型企业&#xff0c;其主要业务涵盖新能源汽车三电系统智能传感器、智能座舱及线控底盘控制器的芯片开发、硬件设计、嵌入式系统开发。以及相关产品的生产…

C++第二十三弹---深入理解STL中list的使用

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、list的介绍 2、list的使用 2.1、构造函数 2.2、赋值操作符重载 2.3、迭代器使用 2.4、容量操作 2.5、元素访问 2.6、修改操作 2.7、其…

从0开始学人工智能测试节选:Spark -- 结构化数据领域中测试人员的万金油技术(三)

分布式计算原理 分布式计算的原理总结一句话就是&#xff1a;分而治之。 把数据分片&#xff0c;存在不同的机器中&#xff0c;解决数据存储的压力。客户端和服务端之间通过相关协议来自动的完成在不同的机器之间进行数据的存取&#xff0c;用户并不感知数据的物理存储结构。 用…

UIKit之App界面Demo

需求 实现简单的APP界面 功能&#xff1a; 实现滚动实现上层、下层横栏滚动时穿透效果&#xff08;永远浮在表面&#xff0c;不跟着滚动&#xff09;。暂用UIView代替&#xff0c;还没学Bar。 分析&#xff1a; 知识点&#xff1a; 实现鼠标拖动的上下滚动&#xff1a;当…

小红书前端2轮面试期望22K,全程问低代码设计

一面&#xff08;通过&#xff09; 1、好&#xff0c;那我们开始把&#xff0c;先简单介绍一下自己的一个经历&#xff0c;以及自己有亮点的项目&#xff1f;balabala 2、你可以这样介绍&#xff1a;在这里边主要负责哪几个项目&#xff0c;哪些项目是比较有亮点的&#xff0…

python用PyPDF2函数库方法对pdf文件切割

烦透了那些软件动不动就要收费&#xff0c;于是自己尝试码程序处理pdf分割。 由于PyPDF2更新到了3.0之后&#xff0c;之前网上的旧代码无法使用&#xff0c;查了半天没出准谱&#xff0c;结果百度AI生成了代码&#xff0c;一试&#xff0c;成了&#xff01; 果然&#xff0c;…

代码随想录-算法训练营day60【单调栈03:柱状图中最大的矩形】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第十章 单调栈part03有了之前单调栈的铺垫,这道题目就不难了。 ● 84.柱状图中最大的矩形https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.htm…

智享直播(三代)2024年:打造24/7实景无人直播,引领年轻资产创业新纪元!

在21世纪的数字化浪潮中&#xff0c;直播行业以其独特的魅力和无限的可能性&#xff0c;正在全球范围内掀起一场前所未有的( keJ0277 )创业革命。而在这场革命中&#xff0c;智享直播&#xff08;三代&#xff09;以其创新的技术理念和前瞻的战略布局&#xff0c;立志于2024年打…

怎么用电脑录制视频?小白也能快速上手

随着网络技术的发展&#xff0c;电脑录制视频已经成为了许多人的日常需求&#xff0c;无论是游戏玩家想录制自己的精彩操作&#xff0c;还是上班族需要录制屏幕演示&#xff0c;一款好用的录屏软件变得尤为重要。可是你知道怎么用电脑录制视频吗&#xff1f;本文将介绍两种电脑…

I2C通信协议

I2C通信协议 项目要求是&#xff0c;通过通信线&#xff0c;是实现单片机读写外挂模块寄存器的功能&#xff0c;至少实现&#xff0c;在指定位置写寄存器和在指定位置读寄存器&#xff0c;实现了读写寄存器&#xff0c;就实现对模块的控制。 MPU6050&#xff0c;OLED&#xf…

【ARM】Fusa Compiler 6.16 LTS的安全认证报告获取

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 了解ARM的Arm Compiler for Embedded FuSa 6.16 LTS的安全认证证书和报告的获取 2、 问题场景 对于使用了ARM DS Gold/Platinum、MDK pro或者Arm Compiler for Embedded FuSa 6.16 LTS产品的客户。在对于最终的产品…

生产问题排查:springboot项目启动时注册nacos失败或运行时从nacos闪退

文章目录 一、引出问题二、解决方案1、使用actuator健康检查2、项目启动时判断nacos是否正常连接3、k8s设置探针 一、引出问题 生产项目是用k8s部署的&#xff0c;最近经常遇到启动时注册不到nacos&#xff08;查找nacos的host地址找不到&#xff09;&#xff0c;或者运行的好…

有文字转语音真人发声吗?这5个配音工具堪比真人配音

青春是一首永不老去的歌&#xff0c;它镌刻在生命的唱片上&#xff0c;永不退色。 每当我们听到那些熟悉的旋律&#xff0c;心中总会涌起一股暖流&#xff0c;仿佛回到了那个充满活力和梦想的年代。借助现代科技的力量&#xff0c;我们可以通过文字转语音软件&#xff0c;让这…

.NET集成DeveloperSharp实现图片的裁剪、缩放、与加水印

&#x1f3c6;作者&#xff1a;科技、互联网行业优质创作者 &#x1f3c6;专注领域&#xff1a;.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 &#x1f3c6;欢迎关注我&#xff08;Net数字智慧化基地&#xff09;&#xff0c;里面…

Apache Doris 基础 -- 数据表设计(表索引)

1、索引概述 索引用于帮助快速过滤或搜索数据。目前&#xff0c;Doris支持两种类型的索引:内置智能索引和用户创建的二级索引。 内置智能索引 排序键和前缀索引:Apache Doris基于排序键以有序的方式存储数据。它为每1024行数据创建一个前缀索引。索引中的键是当前1024行组的…

github搭建个人博客

准备工作 windows安装nodejs windows安装git windows安装hexo 拥有gitee个人账户 配置信息 通过gitee创建博客仓库 登录gitee平台&#xff0c;进入主界面&#xff0c;右侧加号&#xff0c;新建仓库&#xff0c;注意&#xff1a;仓库名称和gitee用户名称一致 生成/添加 SSH 公…

初级网络工程师之入门到入狱(一)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、交换机二、路由器三、DHCP&#xff08;动态主机配置协议&#xff09;四、路由器配置 DHCP自…

【golang】go语言读取Excel表格中的数据

导入库基本用法封装 在Go语言中&#xff0c;可以使用第三方库来读取Excel文件。 常用的库是github.com/tealeg/xlsx&#xff0c;提供了处理Excel文件的功能。 导入库 首先&#xff0c;安装"github.com/tealeg/xlsx"库。可以通过以下命令在终端中安装&#xff1a; g…