23 重构:烟囱式、平台化、中台化的架构

上一讲里,我们介绍了两大类型的系统升级重构方案,还介绍了如何进行重构版本的上线,以及如何平滑地完成新老版本切换的方案。在本讲里,将会具体介绍如何判断系统发展到什么阶段需要重构,以及如何实施重构。

系统稳定性的重构升级

简单、通用的微服务架构如下图 1 所示,它包含一个应用服务和一个数据库作为存储。

图 1:简单、通用的微服务架构图

当上图中展示的架构出现如下一些问题时,可以采用上一讲中提到的“微服务中纯代码维度的升级重构”。

  • 代码日志打印冗余,且因为直接使用大对象进行 JSON 序列化的方式打印日志,进而导致常常出现 CPU 飙升。

  • 代码中未增加监控报警,导致用户先感知线上问题,研发再进行修复。

  • 代码可维护性低,开发需求耗时长,且开发时代码“牵一发而动全身”,产生的 Bug 较多。具体的一些表现是:

(1)一个类中有上千或者上万行代码;

(2)一个类中的某一个方法有上百或者上千行代码;

(3)代码中没有注释;

(4)为了防止影响历史业务,新需求开发均需将原有部分能复用的代码拷贝后,才能修改。

此时,可以将出现上述问题的微服务进行代码重构。具体来说,可以采用 23 种设计模式、SOLID 原则将包含上千上万行代码的类进行重构。此时,重构后的微服务的上线即可对应上一讲里提到的“第一种重构类型:纯代码重构”。它的架构如下图 2 所示:

图 2:纯代码升级重构

完成纯代码的重构后,在日常维护中,当你发现有以下问题时,可以考虑进行包含存储的重构。

  • 随着业务的发展,微服务的流量由每秒几百的 QPS 上升至上千或上万的 QPS 时,可以将微服务的存储从数据库升级为缓存,以便有效应用业务增长带来的流量。

  • 业务或者运营需要对数据库中的四五张表进行聚合(join)分页查询,而数据库面对这些繁杂查询性能会变得非常差。此时可以将微服务的存储从数据库升级为 ElasticSearch,进而满足多维度的富查询。

上述这两类便为包含存储的重构升级,第一个是从数据库升级到缓存,第二个是从数据库升级到 ElasticSearch。它们的架构如下图 3 所示:

图 3:包含存储的架构升级

烟囱式到平台化的重构升级

完成上述两种重构之后,接下来就需要思考什么时候进行另一种存储类型均为数据库存储,但表结构不同的重构了。

在介绍具体实施步骤前,咱们先来聊聊:什么是烟囱式架构。

这里以即时通信作为讨论案例。在 PC 时代,QQ 在即时通信市场的占有率是绝对领先者,相信你也使用过。从技术的抽象层面来看,QQ 主要提供消息发送和消息接收的功能,消息可以是图片、表情、文字、视频、语音等内容。支撑 QQ 消息发送和接收的简版架构如下图 4 所示:

图 4:简版的消息发送和接收架构图

  • 图中编号 1 的模块为安装在电脑里的 QQ 客户端,它主要给用户提供可视化的聊天界面,以及发送和接收其他用户的消息。

  • 编号为 2 的模块为网络接入层,它主要的作用是维护和客户端的网络连接,负责解析客户端发送到服务端的消息和推送其他用户发送的消息给到指定的客户端。在接收和发送消息时,接入层需基于 QQ 自有的数据协议进行消息内容的解码和编码。

  • 编号为 3 的是数据接收模块,它对外提供保存消息的 RPC 接口,并由编号 2 的网络接入层在接收到客户端消息的时候调用。接收模块接收到消息后,会将消息保存至存储中并通知编号 4 的消息发送模块。

  • 编号为 4 的是消息发送模块,它接收到通知后,会读取存储中的待发送消息并进行一定的逻辑处理,然后调用网络接入层进行消息的发送。

关于即时通信后续的发展,你应该就有亲身感受了。为了抓住移动互联网的发展浪潮,腾讯又推出了即时通信的王者级应用:微信。从产品上看,微信和 QQ 在定位、应用界面设计、附加功能设计等方面存在差异。但抽象地从技术和核心功能上分析,两者的功能均是给用户提供消息发送和消息接收。因此,在技术实现上,微信研发团队也需要建设和上述图 4 类似的提供消息发送和接收的技术架构,如下图 5 所示:

图 5:简版的微信消息发送和接收的架构图

从图 5 中不难发现,除了编号 1 的微信 App 和编号 2 的网络接入层模块与图 4 有差异,其余各模块的功能基本上与图 4 类似。网络接入层之所以有差异,是因为接入层需要进行通信协议的解析,而 QQ 和微信的网络通信协议是根据各自的客户端进行定制的,因此会有格式上的差异。

除了微信外,现在大部分在线游戏也都提供了即时通信的能力。因此,游戏团队也需要按上述类似的架构实现自己的消息发送和接收业务系统。

类似上述介绍的这种模式:即系统架构大体上类似,其中只有个别模块存在差异,但各个研发团队还是从零开始建设全部模块的方式,称为烟囱式架构。为了方便你理解,我把QQ、微信以及游戏语音的架构放在一张图中,如下图 6 所示:

图 6:即时通信的烟囱式架构示意图

从上图可以看出,烟囱式架构是一种象形比喻,各个业务研发团队(如 QQ、微信、游戏语音团队)维护了一个类似烟囱式的、包含重复模块的系统架构。除了即时通信这个案例,还有很多其他会产生烟囱式架构的场景,比如电商,电商除了 PC、App、M 页面版本,现在还有很多购物场景,比如自动贩卖机、微信里的分享链接、小程序等。在实现上,如果他们的研发团队是封闭地进行自研,那么也会产生如下图 7 所示的电商版烟囱式架构。

图 7:电商版烟囱式架构示意图

经过前面的分析,烟囱式架构存在的问题其实已经比较明显了,即存在大量的模块重复,进而导致人力重复、成本增加。此时,为了解决这个问题,便可以启动本小节开头提到的升级重构:均为数据库存储,但表结构不同的重构了。

以上述消息接收模块为例,它包含了一个代码进程和对应的消息存储(假设为 MySQL)。为了解决此模块的重复,可以合并 QQ、微信和游戏语音里此模块的代码。同时在前期设计时,各个业务只考虑自己的消息格式,所以它们的数据库的表结构是偏定制的,无法直接被复用,因此在重构时,还需要设计一套全新的、兼容原有三个版本的数据库。此时消息接收模块的重构架构如下图 8 所示:

图 8:消息接收模块融合架构图(三个模块+数据库合并成一个)

完成上述模块的重构融合升级之后,消息发送模块也可以进行类似的融合重构。当所有的可复用模块均完成升级重构后,上述三个不同的即时通信软件的架构演化成如下图 9 的形态:

图 9:融合的系统架构

融合后,三款软件有差异的系统模块依然各自维护,但消息接收和发送模块已经融合为一套。此时,从多个模块融合形成的、支持不同类型使用方的模块,称为平台化模块。而这个重构过程,有一个高大上的名称:从烟囱式架构朝着平台化演化。

平台化到中台化的重构升级

升级重构完成平台化之后,后续三款软件涉及消息接收和发送的新需求,都由平台化模块直接支持。这种需求支撑的模式,看起来十分像这几年兴起的中台化架构,但其实并不是。下面我们具体分析一下,你可以从以下两点来理解。

  • 平台化架构的概念要早于中台化架构。平台化只是将重复模块进行融合,如在平台化之后,未做任何中台化的改造,便不能直接称为中台化模块。

  • 平台化是从降低技术重复的角度出发,从而提升效率,而中台化是在平台化之后,从业务复用的角度出发,进一步提升业务需求的效率。

下面,继续以上一小节的案例作为讨论对象。完成平台化,消灭重复技术之后,如果你遇到以下几种情况,则需要进一步重构,以便完成从平台化到中台化的演化。

  • 融合后的模块代码量庞大、代码中业务逻辑分散。表现就是需求承接时,需要一周时间进行评审,而开发只要一到两天时间,沟通成本巨大。

  • 当出现上述三个之外的新业务场景,融合的平台无法直接支持,而需要大量改造时。

  • 假设 QQ 的某一个需求在平台上开发上线后,微信也提出同样类似的需求,但平台无法直接复用 QQ 的需求,而需要重新开发时。

从平台化到中台化演化升级,可以从业务能力可视化、业务能力在线配置化的方法进行落地改造。

业务能力可视化

仍以上述的数据接收模块为例,可以在平台化之后,将数据接收模块对外的接口流程进行梳理并可视化地展现出来。格式为如下图 10 所示:

图 10:接收数据的接口的可视化展示

流程:数据合法性校验 → 图片压缩 → 图片尺寸裁剪 → 图片转存到 CDN → 语音自动识别成文字 → 保存。

上述这个流程图,大多数情况是在需求提出时由产品经理进行绘制,而在代码上线后便不会再实时更新。而中台化之后,需要开发建设一套业务可视化平台,将业务平台中的代码流程可视化地登记到可视化系统中,同时要保证可视化平台能够在业务代码修改后,实时更新相对应的流程。在实现上,编写业务代码时,可以增加一些代码标记,供可视化平台进行自动化扫描,进而识别业务流程,最终更新到可视化平台的显示界面上。

通过将业务能力可视化之后,前面提到的因为平台化融合了太多代码,导致代码量多、业务无法直接从代码中抽取的问题便解决了。因为可视化之后,业务逻辑可以直接在可视化平台上展现出来,业务方和产品经理不需要和研发来回沟通上周的时间来确认需求,可以极大地降低沟通时间,提升效率。

业务能力配置化

在上述图 10 的流程中,可以看到有些是实心的圆圈,有些是空心的圆圈。空心表示代码执行到此流程节点时会直接跳过,而实心表示会执行此流程节点。流程节点是为空心还是实心,是可配置的,此配置功能可以落地在上述介绍的可视化平台里。

上图 10 的可视化、可配置化流程只有一份,但假设微信在保存消息数据时,不希望图片被压缩而用原图保存;而 QQ 在保存消息数据时,不希望图片尺寸被裁剪。此时,如何通过配置化解决这样的需求呢?答案便是:基于业务身份进行业务流程的配置化。

业务身份是指给 QQ、微信及游戏语音等每一个复用中台能力的应用,都分配一个全局唯一的名称。在进行配置的时候,按业务身份进行隔离,每一个业务身份都拥有属于自己的上述流程的配置,如下图 11 所示:

图 11:按业务身份隔离的私有化流程配置图

在执行时,各个即时通信应用在调用保存消息接口时,需传入自己的业务身份标识。对应的中台模块会根据业务身份获取相对应的配置,并按配置去编排属于此业务身份的流程。

再回顾一下本小节开头提出的平台化架构会遇到的问题。

再来一个新的聊天应用时,无法快速、直接复用已有能力。采用配置化后,可以给新的聊天应用配置一个业务身份,同时基于此应用的需求,去配置它需要使用的业务节点。

QQ 先提出的某一个业务需求并开发上线后,后续微信也想要此功能,但无法快速直接复用。在完成上述业务功能可视化、配置化的基础上,当 QQ 先提出的需求上线后,可视化的工具会将此新功能直接更新到上述流程节点里。只是在 QQ 对应的业务身份的配置里,此新加入的节点为实心。而其他不使用此新功能的业务身份里,此节点为空心。当后续微信需要使用此新功能时,直接将此节点勾选为实心,便可直接复用。

至此,从平台化到中台化的重构升级便具备基本雏形。当前中台化的建设理论还处于初期,有很多种探索的实现方式,但万变不离其宗,它的核心仍然是:在面对不断出现的新的业务场景和形态时(如电商里新出现的社区购等),中台需要快速地复用已有能力,去满足业务新建站点或不断扩宽业务边界的诉求。

本节总结

罗马不是一日建成的,系统建设也是一样,它是随着业务的发展不断演化而来的。当业务体量较小且没有类似像 QQ 和微信的多个前台应用时,没有必要在建设初期就采用平台化或中台化的建设方案。因为它们的建设人力成本和消耗的机器资源也更高。

一个系统在建设时,假如预期未来的三到五年的用户量并不会增长太大,可以先采用烟囱式的架构,快速地满足业务需求。当发展到一定体量后,再发起从烟囱式到平台化及中台化演化即可。毕竟能够发展到百万、千万用户体量的系统是少数,所有的系统都提前建设会存在较大可能的成本浪费。

最后,我再给你留一个讨论话题:当前你所负责的系统处在什么样的阶段,是烟囱式、平台化或中台化的架构吗?它存在什么样的问题,你觉得是否有必要准备启动升级计划了。欢迎你在留言区说出你的想法,我们一起讨论。

这一讲就到这里,感谢你学习本次课程,下一讲是本专栏的最后一篇内容,我想和你聊聊关于程序员发展的话题:抓住本质,是成为技术专家的不二法则。

最后,我邀请你为本专栏课程进行结课评价,因为你的每一个观点都是我和拉勾教育最关注的点。点击链接,既可参与课程评价。编辑会随机抽 5 位同学送精美礼品喔。

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

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

相关文章

AutoBackgroundBackButton 在ScrollView上方自动根据返回键按钮下方内容动态改变颜色。自动变色返回键

在日常有时候有一些为了优化体验的需求。AutoBackgroundBackButton 一个可以根据按钮下方背景颜色动态的改版返回键自定义ImageView。这里只展示了黑白切换方式,你如果还有其他需求可以参考颜色校验来自己实现切换对应颜色按钮。【例如白色背景展示黑色样式&#xf…

Python urllib 爬虫入门(1)

本文主要为Python urllib类库函数和属性介绍及一些简单示例。 目录 urllib爬取网页 简单示例 写入文件 其他读取方法 readline函数 readlines函数 response属性 当前环境信息 返回状态码 返回url地址 对url进行编码与解码 写入文件 总结 urllib爬取网页 通过pyth…

PotatoPie 4.0 实验教程(35) —— FPGA实现摄像头图像二值化膨胀效果

手机扫码 链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 什么是图像二值化膨胀,有什么作用? 图像二值化膨胀是图像处理中的一种基本操作,它用于扩展和增强二值图像中的白色区域。具体而言,二值化膨胀操作…

【论文笔记】Training language models to follow instructions with human feedback A部分

Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 : 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式;模型架构是基于 Transformer 的叠加解码器(掩码自注意…

LeetCode55:跳跃游戏

题目描述 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 解题思想 每次…

update_min_vruntime()流程图

linux kernel scheduler cfs的update_min_vruntime() 看起来还挺绕的。含义其实也简单,总一句话,将 cfs_rq->min_vruntime 设置为: max( cfs_rq->vruntime, min(leftmost_se->vruntime, cfs_rq->curr->vruntime) )。 画个流…

滑动窗口详解

目录 一、滑动窗口的特定步骤: 二、题目解析 1、⻓度最⼩的⼦数组---点击跳转题目 3、最⼤连续 1 的个数 III----点击跳转题目 4、将 x 减到 0 的最⼩操作数----点击跳转题目 5、⽔果成篮----点击跳转题目 滑动窗口是双指针算法中细分的一种,它由暴…

PDF高效编辑器,支持修改PDF文档并转换格式从PDF文件转换成图片文件,轻松管理你的文档世界!

PDF文件已成为我们工作、学习和生活中不可或缺的一部分。然而,传统的PDF阅读器往往只能满足简单的查看需求,对于需要频繁编辑、修改或转换格式的用户来说,就显得力不从心。现在,我们为您带来一款全新的PDF高效编辑器,让…

挑战一周完成Vue3项目Day3: 品牌管理+平台属性管理+SPU管理+SKU管理

一、真实接口替换mock接口 (1)替换各个环境下的服务器地址( .env.development、.env.production、.env.test ) VITE_SERVE"http://sph-api.atguigu.cn" (2) 配饰代理跨域:vite.con…

根据标签最大层面ROI提取原始图像区域

今天要实现的任务是提取肿瘤的感兴趣区域。 有两个文件,一个是nii的原始图像文件,一个是nii的标签文件。 我们要实现的是:在标签文件上选出最大层面,然后把最大层面的ROI映射到原始图像区域,在原始图像上提裁剪出ROI…

PLC通过Modbus转Profinet网关连接变频器与电机通讯

Modbus转Profinet网关(XD-MDPN100)是一种能够实现Modbus协议和Profinet协议之间转换的设备。Modbus转Profinet网关可提供单个或多个RS485接口,PLC作为控制中枢,变频器作为控制电机转速,通过Modbus转Profinet网关&#…

瑞米派实时系统与EtherCAT移植-米尔Remi Pi

1.概述 Remi Pi采用瑞萨RZ/G2L作为核心处理器,该处理器搭载双核Cortex-A551.2GHzCortex-M33200MHz处理器,其内部集成高性能3D加速引擎Mail-G31 GPU(500MHz)和视频处理单元(支持H.264硬件编解码),16位的DDR4-1600 / DDR3L-1333内存…

Webshell绕过技巧分析之-base64编码和压缩编码

在网络安全运营,护网HVV,重保等活动的过程中,webshell是一个无法绕过的话题。通常出现的webshell都不是以明文的形式出现,而是针对webshell关键的内容进行,混淆,编码来绕过网络安全产品,例如IDS…

计算机提示msvcp110.dll是什么意思?msvcp110.dll丢失恢复办法

在Windows操作系统中,动态链接库(DLL)扮演着至关重要的角色,它们是实现程序间代码共享和模块化设计的关键组件。msvcp110.dll,作为Microsoft Visual C 2012运行时库的一个组成部分,是理解现代软件开发和维护…

【酱浦菌-爬虫技术细节】解决学术堂爬虫翻页(下一页)问题

首先我们通过css选择器获取页码信息,这里的css选择器,选择的是含有a标签的所有li标签,代码如下: li html_web.css(div.pd_c_xslb_left_fenye ul li>a) for li in li:li_url li.css(a::attr(href)).get()li_num li.css(a::t…

STM32入门_江协科技_3~4_OB记录的自学笔记_软件安装新建工程

3. 软件安装 3.1. 安装Keil5 MDK 作者的资料下载的连接如下:https://jiangxiekeji.com/download.html#32 3.2. 安装器件支持包 因为新的芯片层出不穷,所以需要安装Keil5提供的器件升级版对软件进行升级,从而支持新的芯片;如果不…

unity-C#调用百度千帆AppBuilder的OpenApi

目录 功能描述准备工作百度智能云账号创建应用编辑应用创建Api秘钥Api调用流程unity代码Unitywebrequest非流式流式注意事项 Restsharp 功能描述 使用百度千帆AppBuilder平台,通过api调用的方式实现AI大模型对话功能(文字) 准备工作 百度智能云账号 请自行在百度智能云进行…

力扣---二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出: []实现方法&…

nginx+Tomcat动静分离

本⽂的动静分离主要是通过nginxtomcat来实现,其中nginx处理图⽚、html等静态的⽂ 件,tomcat处理jsp、do等动态⽂件. 实验环境 192.168.200.133 nginx反向代理 192.168.200.129 static 192.168.200.130 dynamic 步骤 修改三台主机名 [rootadmin ~]#…

关于Centos 7/8 网络设置 与工具连接

网络三步曲的配置 1、首先更改虚拟机的网络配置 查看子网地址以及网关 如果有要求需要更改IP地址,规定第三位是指定数值,那么需要全部更改 例如,IP地址为192.168.200.30 其中200为重点,更改时为以下步骤 1、点击DHCP设置&#x…