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

架构师面试(三十九):微服务重构单体应用

题目:

今天在数字化转型趋势下,很多企业(比如传统软件公司、产业互联网公司、部分互联网公司等)都会面临着需要将【复杂的单体应用系统】进行【服务化重构】的问题。

如果你是该业务系统的架构师,带领大概10人左右的后端研发团队,你认为需要考虑哪些关键事项呢?你会如何推动这个复杂的业务系统进行架构调整?你心中的战略蓝图或规划是怎样的?

解析:

将一个【复杂的单体业务系统】重构为【微服务系统】,相信是绝大部分后端工程师或架构师都想参与和负责的一个含金量很高的项目。在项目开始之前,我们需要对其有一个宏观的蓝图规划。

首先,切忌在单体系统上直接大规模重构代码;原因有二:一是存在系统不稳定风险,毕竟单体业务系统还需要正常运行很长一段时间,还需要继续为用户提供服务,大规模的重构一定会(虽然说得很绝对,但应该没有人会做到大规模重构之后还能安全上线的)给单体系统带来 运行风险;二是新业务还需要继续在单体系统上面迭代和升级,毕竟【重构系统】是技术部门的事情,产品部门很少会关心,产品部门需要持续将新功能落地。

不能在单体系统上面直接 “动手术”,那应该怎么做呢?【扩展】是软件系统永恒不变的主题!也就是直接在单体系统之外,设计一套新的系统 ——  【微服务系统】。

【微服务系统】的设计,最大的难点有两个:一是 【服务治理】,这是技术层面的问题,涉及 服务发布、服务订阅、服务发现、服务通讯、服务容错、服务扩容和缩容、服务注销等分支细节(我们在P7架构师课上对这些点都做过详细分析和讲解);二是【服务拆分】,这是业务层面的问题,需要根据业务流程、业务规模、业务特性、组织架构等方对业务按 “高内聚、低耦合” 原则进行合理拆分(后面我们会深入分析 基于 “信息系统架构” 对短视频系统进行服务化拆分的案例)。

到目前为止,我们有一个可以实际运行的【单体业务系统】,有一个停留在纸上的设计版的【微服务系统】,那么接下来如何落地呢?如下图所示:

引入一个【路由器】模块,其职责是判断 http 请求接口的提供方,若是老的http请求,则路由到老的【单体业务系统】,若是新的http请求,则路由到新的【微服务系统】。在具体实施时,通常有这样几种情况:

  1. 对于产品新开发的功能,直接将代码写在【微服务系统】中,尽量避免继续在【单体业务系统】上面迭代;

  2. 对于现有功能的扩展,直接在【微服务系统】中进行重写,尽量避免在【单体业务系统】上面对现有接口进行修改;

  3. 对于【单体业务系统】中很久未修改且已经非常稳定的模块,可直接将其作为独立的服务,迁移到【微服务系统】中(当然,这个过程需要进行代码的修改)。

实际的生产过程会存在各种各样的情况,比如:【微服务系统】需要访问【单体业务系统】中的业务数据时,需要怎么处理呢?(1)直接访问数据库;(2)维护一份数据拷贝,并与单体业务系统的业务数据保持同步;(3)通过访问单体业务系统的API。我们通常的做法是第(3)种,即由【微服务系统】和【单体业务系统】分别提供【胶水代码】,实现两套系统之间的交互。(单体业务系统也是有可能访问新的微服务系统中数据的!)

随着新业务不断迭代,老的单体业务系统中模块的迁移,新的【微服务系统】会越来越丰富,老的【单体业务系统】会越来越收缩,直至消失;在整个过程中,【路由器】需要根据配置和规则不断地将越来越多的 http 请求路由到【微服务系统】。

这样的一个蓝图,最大的好处是:不影响正常的业务迭代、大大降低线上系统运行风险、成本最低收益最高!作为架构师或项目的负责人,心中需要有上述的这样一个蓝图或战略目标;当然,在实施蓝图的过程中,会碰到各种各样的技术问题,我们会在后面的短文中持续分析和讲解!

最后总结一下关键点:

  1. 切忌在单体系统上直接大规模重构代码;

  2. 设计微服务系统,解决【服务治理】和【服务拆分】两大难题;

  3. 引入【路由器】和【胶水代码模块】,在业务迭代和重构过程中,将【业务单体系统】越做越小,直至做没。

http://www.xdnf.cn/news/16980.html

相关文章:

  • 【C++】语法基础篇
  • Javascript面试题及详细答案150道(046-060)
  • Flask全栈入门:打造区块链艺术品交易所
  • 风光储并网协同运行simulink仿真模型实现
  • transformer与神经网络
  • Azure DevOps — Kubernetes 上的自托管代理 — 第 5 部分
  • 进程间通信:管道与共享内存
  • Antlr学习笔记 02、使用antlr4实现简易版计算器
  • 【无标题】标准 I/O 中的一些函数,按功能分类说明其用法和特点
  • 【LeetCode刷题集】--排序(一)
  • clocking_cb驱动之坑
  • BackgroundTasks 如何巧妙驾驭多任务并发?
  • 测试-概念篇(3)
  • <PhotoShop><JavaScript><脚本>基于JavaScript,利用脚本实现PS软件批量替换图片,并转换为智能对象?
  • Linux 逻辑卷管理
  • 深入理解Spring中的循环依赖及解决方案
  • ssh连接VirtualBox中的Ubuntu24.04(win11、putty、NAT 模式)
  • 模型蒸馏(Distillation):原理、算法、应用
  • 每日任务day0804:小小勇者成长记之药剂师的小咪
  • 深入剖析Java Stream API性能优化实践指南
  • AgxOrin平台JetPack5.x版本fix multi-cam race condition 补丁
  • (2023ICML)BLIP-2:使用冻结图像编码器和大语言模型引导语言-图像预训练
  • Ubuntu共享文件夹权限设置
  • 【数据结构初阶】--顺序表(一)
  • 使用AWS for PHP SDK实现Minio文件上传
  • nodejs 封装方法将打印日志输出到指定文件
  • mybatis-plus报错Caused by: java.sql.SQLException: 无效的列类型: 1111
  • 论文Review LIO Multi-session Voxel-SLAM | 港大MARS出品!体素+平面特征的激光SLAM!经典必读!
  • Spring Boot 应用结合 Knife4j 进行 API 分组授权管理配置
  • 【世纪龙科技】汽车自动变速器拆装虚拟实训软件