基于公共业务提取的架构演进——外部依赖防腐篇
背景
有了前两篇的帐号权限提取和功能设置提取的架构演进后,有一个问题就紧接着诞生了,对于诸多业务方来说,关键数据源的迁移如何在各个产品落地?

这么关键的数据,又做了如此大的调整,从业务方角度不得不考虑两个问题:
- 如何降低各个业务服务的接入难度?
- 即使各个服务都费力的将代码接入,一旦上线后发现问题如何快速补救?
这是一个全局性的问题,需要统一考虑,否则之前看似合理的架构优化却可能因为对接时的实际困难而落不了地。
也就是这些非功能层面的问题,却有可能让一个架构优化中途夭折,我们需要从软件工程层面解决这些问题。
2. 思路
从业务对接的角度来看,我们要解决两个典型问题:
- 如何减少对接的工作量;
- 如何降低对接后的上线风险;
这两个问题,我们通过以下4步来解决。
2.1 代码调用归一化处理
当系统中各个业务层都直接访问DB时,我们是很难作数据源调整的,所以我们首先要作的是:数据访问的归一化处理
。简单讲:就是把业务层对DB的访问收扰到一个公共库中,包括两个层面:
- 服务内部,所有业务接口访问帐号设置类数据都通过公共库来访问;
- 系统层面,所有服务访问帐号设置类数据都通过公共库来访问;
如下图所示:
在这个收拢的过程中我们主要做几件事:
- 统一封装数据的访问接口,各个业务都走相同的接口来访问数据;
- 统一数据格式,例如:所有业务访问帐号都返回同一套数据结构体;
- 数据源没有改变,但各个服务由直接依赖DB改为依赖公共库;
2.2 接入新数据源
作了代码调用的归一化处理后,我们接入新数据源基本只需要改动公共库。具体工作为:
- 抽象一套数据访问的接口,让新数据源和老数据源都实现同一套接口;
- 从新数据源获取到数据后,可能需要做下数据格式的转换,让新、老数据源返回的数据格式统一;
抽象接口定义类图如下所示:
这套接口,屏蔽了老数据源和新数据源的获取差异,这样业务服务接入新数据源的工作量能降到最小。
2.3 快速回退支持
通过前面两步,公共库已经提供了新、老两套数据访问接口,业务方可能只需要一行代码改动做个选择即可。这里我们想讨论的一个问题是:当接入新数据源上线后,发现问题如何处理?
- 第一种选择:把版本回退,回退到老数据源的版本,这会带来其它修改(如客户故障修复)也被牵连回退;
- 第二种选择:我们做一个配置开关,通过修改配置,快速回退到老版本,其它修改都不受影响;
不难发现,第二种方式明显更稳妥,配置简单示意如下:
# AccountStore的实现版本选择
AccountStoreMode = v2
可能还需要在AccountStore的初始化代码中作一点改动来支持版本选择,比较简单,这里就不示例了。
2.4 降级处理
回退主要是解决已经出故障后如何快速恢复的问题,也就是不论我们恢复多快,至少已经有一部分用户受到了影响,那是否有什么办法来避免故障发生呢?
有,我们可以做数据获取的降级处理,做法也比较简单:当从新数据源获取不到时,可以尝试从老数据源再获取一次。
有同学可能有疑问:降级会不会带来数据的正确性问题?
确实有一定的概率,用户的帐号权限已经在新数据源发生变更,降级访问老数据获取到的还是旧数据,如果用户正好要使用依赖此权限项的功能,则有一定概率与用户预期不符。
但是问题在于:当面临帐号都获取不到的产品可用性问题时,个别功能是否符合预期这类局部问题,还有那么重要吗?而且还是一定概率。
这时候我们就要做权衡,评估哪个问题带来的影响更小,两害取其轻。
软件开发中往往很难有完美的方案,有时候因为技术复杂度,有时候因为成本,这时候做权衡就很重要,选一个
我们能够掌控
、团队有能力实施
、结果有一点折扣但也能接受
的方案,往往更实用。
小结
本文以前面两篇文章账号权限提取和功能设置提取为背景,介绍了当外部依赖发生变化时,如何及时调整业务服务的结构设计。通过引入外部依赖防腐层,来减化架构调整带来的对接工作量,并降低对接新数据源的上线风险。
在软件设计中,防腐层往往被描述为一个适配器,用以将外部依赖和内部业务逻辑解耦。还是之前那个观点,名称叫什么不重要,重在能用它解决项目中的实际问题。
防腐层的适用范围远不止于此,其实从长远角度考虑,产品系统中很多模块都应该设计外部依赖防腐层,像数据库、外部服务接口、消息队列、缓存等。这些看似稳定不变的基础设施,却会在某天因为一个市场风向或客户需求,而被公司要求果断的替换掉,例如:信创带来的技术国产化浪潮……
参考阅读
- 从帐号权限提取的视角来看架构演进
- 从功能设置提取的视角来看架构演进
相关文章:

基于公共业务提取的架构演进——外部依赖防腐篇
背景 有了前两篇的帐号权限提取和功能设置提取的架构演进后,有一个问题就紧接着诞生了,对于诸多业务方来说,关键数据源的迁移如何在各个产品落地? 要知道这些数据都很关键: - 对于帐号,获取不到帐号信息是…...

uniapp小程序接入腾讯云【增强版人脸核身接入】
文档地址:https://cloud.tencent.com/document/product/1007/56812 企业申请注册这边就不介绍了,根据官方文档去申请注册。 申请成功后,下载【微信小程序sdk】 一、解压sdk,创建wxcomponents文件夹 sdk解压后发现是原生小程序代…...
Sass 最基础的语法
把每个点最简单的部分记录一下,方便自己查找 官方文档链接 Sass 笔记 1. & 父选择器,编译后为父选择器2. : 嵌套属性3. $ 变量3.1 数据类型3.2 变量赋值3.3. 数组3.4. map 4. 算数运算符5. #{}插值语法5.1 可以在选择器或属性名中使用变量5.2 将有引…...

2023年11月数据库流行度最新排名
点击查看最新数据库流行度最新排名(每月更新) 2023年11月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多,这个数据库就被认为越受欢迎。这是一个领先指标。原始数…...

JavaEE-部署项目到服务器
本部分内容为:安装依赖:JDK,Tomcat,Mysql;部署项目到服务器 什么是Tomcat Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器。 为什么我们需要…...

计算机网络期末复习-Part1
1、列举几种接入网技术:ADSL,HFC,FTTH,LAN,WLAN ADSL(Asymmetric Digital Subscriber Line):非对称数字用户线路。ADSL 是一种用于通过电话线连接到互联网的技术,它提供…...

Redis系列-Redis过期策略以及内存淘汰机制【6】
目录 Redis系列-Redis过期策略以及内存淘汰机制【6】redis过期策略内存淘汰机制算法LRU算法LFU 其他场景对过期key的处理FAQ为什么不用定时删除策略? Ref 个人主页: 【⭐️个人主页】 需要您的【💖 点赞关注】支持 💯 Redis系列-Redis过期策略以及内存淘…...

多语言翻译软件 Mate Translate mac中文版特色功能
Mate Translate for Mac是一款多语言翻译软件,Mate Translate mac可以帮你翻译超过100种语言的单词和短语,使用文本到语音转换,并浏览历史上已经完成的翻译。你还可以使用Control S在弹出窗口中快速交换语言。 Mate Translate Mac版特色功能…...

Python GUI标准库tkinter实现与记事本相同菜单的文本编辑器(一)
介绍: Windows操作系统中自带了一款记事本应用程序,通常用于记录文字信息,具有简单文本编辑功能。Windows的记事本可以新建、打开、保存文件,有复制、粘贴、删除等功能,还可以设置字体类型、格式和查看日期时间等。 …...
Decimal.ToString()堆栈溢出异常
Decimal.ToString() 堆栈溢出异常 导致以下报错: A process serving application pool XXX suffered a fatal communication error with the Windows Process Activation Service. The process id was 7132. The data field contains the error number. Application pool …...

com.genuitec.eclipse.springframework.springnature
Your IDE is missing natures to properly support your projects. Some extensions on the eclipse marketplace can be installed to support those natures. com.genuitec.eclipse.springframework.springnature 移除 <nature>om.genuitec.eclipse.springframework.…...

wangeditor富文本编辑器的使用(vue)
官网 官方demo 参考 安装 yarn add wangeditor/editor yarn add wangeditor/editor-for-vue 封装的富文本组件 <template><div style"border: 1px solid #ccc"><Toolbarstyle"border-bottom: 1px solid #ccc":editor"editorRef"…...

物联网水表有什么弊端吗?
物联网水表作为新一代智能水表,虽然在很大程度上提高了水资源的管理效率,但也存在一定的弊端。在这篇文章中,我们将详细讨论物联网水表的弊端,以帮助大家更全面地了解这一技术。 一、安全隐患 1.数据泄露:物联网水表通…...

安卓 车轮视图 WheelView kotlin
安卓 车轮视图 WheelView kotlin 前言一、代码解析1.初始化2.初始化数据3.onMeasure4.onDraw5.onTouchEvent6.其他 6.ItemObject二、完整代码总结 前言 有个需求涉及到类似这个视图,于是在网上找了个轮子,自己改吧改吧用,拿来主义当然后&…...
升级Redisson版本兼容问题
升级版本:从 3.10.6 升级到3.18.0 报错: java.io.IOException: Unsupported protocol version 252 java.io.IOException: Unsupported protocol version 252at org.jboss.marshalling.river.RiverUnmarshaller.start(RiverUnmarshaller.java:1375)at org.redisson…...
前端框架Bootstrap
前端框架Bootstrap 该框架已经帮我们写好了很多页面样式,如果需要使用,只需要下载对应文件 直接CV拷贝即可 在使用Bootstrap的时候,所有的页面样式只需要通过修改class属性来调节即可 什么是Bootstrap Bootstrap是一个开源的前端框架…...

Flink SQL TopN语句详解
TopN 定义(⽀持 Batch\Streaming): TopN 对应离线数仓的 row_number(),使⽤ row_number() 对某⼀个分组的数据进⾏排序。 应⽤场景: 根据 某个排序 条件,计算 某个分组 下的排⾏榜数据。 SQL 语法标准&am…...
k8s之数据卷
一,存储卷 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态&#…...
服务器网络
配置 通常使用ping查看网络 如果能ping通,不能ssh登陆,安装 sudo apt update sudo apt install openssh-server如果已经安装,查看防火墙状态,inactive(不活跃) sudo ufw status sudo ufw allow ssh sudo ufw reload查看ssh状态 s…...

YOLOv8-seg 分割代码详解(一)Predict
前言 本文从 U-Net 入手熟悉分割的简单方法,再看 YOLOv8 的方法。主要梳理 YOLOv8 的网络结构,以及 Predict 过程的后处理方法。 U-Net 代码地址:https://github.com/milesial/Pytorch-UNet YOLOv8 代码地址:https://github.com/…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...