想从单体架构演进到分布式架构,SBA 会是一个不错的选择
摘要:SBA 可以看成是单体架构和微服务架构之间的一个折中方案,它也是按照业务领域进行服务划分,但服务划分的粒度相比微服务要更粗。从单体架构演进到 SBA,会比直接演进到微服务架构更加容易。
本文分享自华为云社区《从分层架构到微服务架构(五)之服务化架构》,作者:元闰子。
前言
从本文开始,我们进入了《从分层架构到微服务架构》系列中分布式架构的介绍,本文要介绍的是服务化架构(Service-Based Architecture,SBA)。
SBA 可以看成是单体架构和微服务架构之间的一个折中方案,它也是按照业务领域进行服务划分,但服务划分的粒度相比微服务要更粗。SBA 与微服务架构一大不同是,它允许各个服务间共享同一个数据库实例,这也使得 SBA 在架构上既有单体架构的特点,也有分布式架构的特点,显得更加的灵活。因此,从单体架构演进到 SBA,会比直接演进到微服务架构更加容易。
架构视图
基础视图
SBA 的基础架构视图分成 3 部分:
- User Interface,作为系统的接入口,接收客户端的请求,并转发到业务服务。。
- DomainServices,业务服务按照领域进行划分,分开部署、业务独立。
- Database,服务间共享的数据库实例,因为数据库实例只有一个,所以可以支持 ACID 事务。

使用 SBA 的系统通常只会划分 4 ~ 12 个服务,避免产生过多的数据库连接。服务数量不多,也决定了 SBA 中的服务相比微服务架构中的服务有着更粗的粒度。User Interface 与服务间通过远程通信协议来完成业务往来,常见的通信方式有REST、RPC、消息队列等。需要注意的是,SBA 是不允许服务间通信的,这与微服务架构有着本质的区别。
大多数情况下,SBA 中的服务只有一个或者少量实例,与微服务动辄成百上千个实例有着很大的区别。主要是因为 SBA 服务粒度更粗,无法做到像微服务那样精准的按需扩容,扩容太多反而会导致资源的浪费。
SBA 的另一大特点是允许所有服务共享同一数据库实例,使得它能够直接将传统单体架构的那一套 SQL 查询逻辑、ACID 事务搬过来,让架构的演进更加的平滑。不过,共享数据也会带来一些问题,比如数据模型变更的影响范围更大,后面会在“数据拆分”一节详细讲述。
拆分 User Interface
在大型系统中,单一的 User Interface 可能导致代码耦合、性能瓶颈等问题,这时候我们可以进一步对它进行拆分。拆分的方法可以是基于业务领域的拆分,业务相关的几个服务使用同一个 User Interface;或者基于服务的拆分,为每个服务都配备一个 User Interface。

拆分 Database
类似地,我们也可以对数据库进行拆分,可以拆分成几个服务共享一个实例;也可以像微服务架构中那样,每个服务独享一个实例。数据库拆分的原则就是:确保数据是解耦的,不会被其他服务所依赖,避免出现跨库查询或服务间通信。

增加 API 网关
我们也可以在 User Interface 和 Domain Services 之间增加一个 API 网关层,提供流控、鉴权、指标统计、服务发现等公共能力,进一步提升系统架构的安全性、可靠性、可维护性。

业务服务的设计
SBA 中的服务具有较粗的粒度,因此在业务服务的架构设计上通常也会用到一些单体架构模式,常见的有分层架构和基于领域的组件化架构。

不管是分层架构还是组件化架构,通常都需要增加一个 API 层,负责编排和转发来自 User Interface 的业务请求。下面以订单创建流程作为示例。
假设现在有一个订单服务 OrderService,当它的 API 层接收到来自 User Interface 的订单创建请求时,API 层协调会各个组件依次完成如下的几个业务流程 :
- 调用订单组件,完成订单ID、订单内容的生成。
- 调用支付组件,完成用户的扣款。
- 调用库存组件,更新商品的库存数量。
因为这些业务流程都是在同一个服务内完成,当其中的某个流程异常后,我们很容易通过数据库的 ACID 事务来完成回滚,从而能够确保数据的强一致性。
相比在微服务架构之下,订单创建请求往往需要订单微服务、支付微服务、库存微服务之间协作来完成,这就涉及到分布式事务,也即 BASE(Basic Availability, Soft state, Eventual consistency) 事务。BASE 事务更加的复杂,而且无法保证数据的强一致性。 当然,更粗的服务粒度也会带来服务可用性问题,比如在订单服务例子中,你会因为订单ID生成逻辑的变更而升级整个服务,也会因为库存组件中的一个BUG导致整个服务的故障。
所以,服务粒度的粗与细,实际上也是数据一致性和服务可用性的一次 trade-off。
数据拆分
服务间共享数据库使得系统具有更强的数据完整性和一致性,但简单的单库单表数据模型会带来耦合的问题。
在单库单表的模型下,我们大概率会这么实现,将与数据库操作相关的实体对象、SQL 逻辑全部封装在一个共享的 shared lib 库上,供所有业务服务复用:

这样的实现方式虽然简单,但是会带来“牵一发而动全身”的问题。假设某个服务所用到的某个字段类型需要变化,势必会修改表结构和 shared lib 库,而这两者是所有服务共用的,因此也就会导致所有服务都需要升级重新上线。这样的耦合会给 SRE 带来极大的困扰,一点也不敏捷。
更好的方法是根据业务对数据进行拆分,将相对独立的数据拆分成多个表,每个表都有一个独立的 lib 库,对于公共表,则有一个 common lib 库,各服务按需依赖。对于 common lib 库的变更,我们还可以通过版本控制来尽量降低影响范围,但必须在 common lib 进行版本升级时保持向后兼容。

架构评分

SBA 虽然是分布式架构,但是也保留了单体架构下的一些特点,在架构上具有较高的灵活性,也使得它在各方面的评分都比较高,没有明显的缺点。
SBA 是一个 domain-partitioned 的架构,因此适合使用领域驱动设计来进行领域限界上下文的划分,进而规划出业务独立的服务。服务间业务独立,而且不会相互间通信,也就意味着具有更好的 Testability。
前文有提到过,SBA 虽然支持服务实例扩容,但是更粗的服务粒度会导致扩容的性价比并不高,因此 Scalability 和 Elasticity 得分不高。
Scalability 和 Elasticity的差异:
- Scalability 通常指软件系统在不中断业务的前提下,通过 scale-up 或 scale-out 等手段来应对更高业务负载,强调的是软件系统应对高负载的能力。
- Elasticity 通常指硬件系统能够根据实际的业务负载情况,适时增加或减少硬件资源,强调的是硬件资源的高效利用。
总结
如果你打算从单体架构演进到分布式架构,SBA 会是一个不错的选择:
- 相比单体架构,SBA 按照业务进行服务拆分,在业务解耦、开发流程敏捷等方面有着明显的优势。
- 相比其他分布式架构,SBA 有着更粗的服务粒度,因此也得以减少了服务间的远程调用、网络带宽消耗,受网络故障的影响更小。
- 服务间共享数据库使得 SBA 支持 ACID 事务,在数据一致性方面具有良好的表现,但我们还是应该尽量按照业务进行分表,避免出现严重的数据耦合。
- 在架构评分上,SBA 各方面评分都不错,没有明显的缺点,是典型的“六边形战士”。
参考
- Fundamentals of Software Architecture (Chapter 13. Service-Based Architecture Style), Mark Richards, Neal Ford
- Service-Based Architecture as an Alternative to Microservice Architecture, Matt Fletcher
- What is the difference between scalability and elasticity?, stackoverflow
想从单体架构演进到分布式架构,SBA 会是一个不错的选择的更多相关文章
- 小D课堂 - 新版本微服务springcloud+Docker教程_2_01传统架构演进到分布式架构
笔记 第二章 架构演进和分布式系统基础知识 1.传统架构演进到分布式架构 简介:讲解单机应用和分布式应用架构演进基础知识 (画图) 高可用 LVS+keepalive :负载均衡的知识点 1. ...
- 新东方APP技术架构演进, 分布式系统架构经验分享
今天的演讲题目是"新东方APP技术架构演进, C端技术经验分享" 作者:张建鑫, 曾任IBM高级软件架构师, 滴滴高级技术专家, 现任新东方集团高级技术总监 古代东西方的思想家都产 ...
- SpringCloud(1) 架构演进和基础知识简介
一.传统架构演进到分布式架构 简介:讲解单机应用和分布式应用架构演进基础知识 (画图) 高可用 LVS+keepalive 1.单体应用:开发速度慢.启动时间长.依赖庞大.等等 2.微服务:易开发.理 ...
- 基于SpringCloud分布式架构
基于SpringCloud分布式架构 为什么要使用分布式架构 Spring Cloud 专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖 分布式/版本化配置 服务注册和发现 路由 Servic ...
- Slithice 分布式架构设计
项目原因: 参与过各种 分布式项目,有 Socket,Remoting,WCF,当然还有最常用的可以跨平台的 WebService. 分布式编码的时间浪费: 但是,无一例外的,开发分布式程序的开发遵循 ...
- SpringCloud 亿级流量 架构演进
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 前言 Crazy ...
- 复杂分布式架构下的计算治理之路:计算中间件 Linkis
前言 在当前的复杂分布式架构环境下,服务治理已经大行其道.但目光往下一层,从上层 APP.Service,到底层计算引擎这一层面,却还是各个引擎各自为政,Client-Server 模式紧耦合满天飞的 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- MemSQL分布式架构介绍(一)
最近在了解MemSQL架构,看了些官方文档,在这里做个记录,原文在这里:http://docs.memsql.com/latest/concepts/distributed_architecture/ ...
- 安居客Android项目架构演进
入职安居客三年从工程师到Team Leader,见证了Android团队一路走来的发展历程.因此有心将这些记录下来与大家分享,也算是对自己三年来一部分工作的总结.希望对大家有所帮助,更希望能得到大家宝 ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (119)-- 算法导论10.3 4题
四.用go语言,我们往往希望双向链表的所有元素在存储器中保持紧凑,例如,在多数组表示中占用前m 个下标位置.(在页式虚拟存储的计算环境下,即为这种情况.)假设除指向链表本身的指针外没有其他指针指向该链 ...
- 【前端开发】基于vue+elemnt-ui流程图设计器解决方案
前言 越来越多的企业都在研发低代码平台,其中流程引擎是核心之一,拥有一个可以拖拽设计审批流程的设计器是相当重要的. 介绍 审批流程设计器是一种工具,用于创建和设计审批流程.它通常是一个可视化的设计器界 ...
- Java 基础学习第一弹
1. equels和==的区别 equals方法用于比较对象的内容是否相等,可以根据自定义的逻辑来定义相等的条件,而==操作符用于比较对象的引用是否相等,即它们是否指向同一块内存地址.equals方法 ...
- QT中级(2)QTableView自定义委托(二)实现QProgressBar委托
同系列文章 QT中级(1)QTableView自定义委托(一)实现QSpinBox.QDoubleSpinBox委托 QT中级(2)QTableView自定义委托(二)实现QProgressBar委托 ...
- QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托
1 写在前面的话 我们在之前写的<QT(7)-初识委托>文章末尾提到,"使用一个类继承QStyledItemDelegate实现常用的控件委托,在使用时可以直接调用接口,灵活实现 ...
- [Python急救站课程]叠加等边三角形的绘制
叠加等边三角形的绘制 from turtle import * penup() fd(-100) pendown() pensize(10) seth(60) fd(200) seth(-60) fd ...
- JavaScript 语法:流程控制语句
作者:WangMin 格言:努力做好自己喜欢的每一件事 JavaScript流程控制语句的三种基本结构:顺序结构,选择结构,循环结构 顺序结构 从上到下执行的代码就是顺序结构,程序默认就是由上到下顺序 ...
- 可怕!.Net 8正式发布了,.Net野心确实不小!
随着三天.NET Conf 2023的会议结束了,.Net 8正式发布了. .Net 8是官方号称有史以来性能最快的一个版本了. .Net 8 增加了数以千计的性能.稳定性和安全性改进,以及平台和工具 ...
- 使用 TortoiseGit 在两个项目之间共享代码(cherry-pick)
需求:项目 A 需要新增项目 B 的部分代码,要求不变更 commit message 信息 做法 项目 A 新增上游 Remote,Remote URL 为 项目 B 的 URL 新增方式:依次点击 ...
- 3种Sentinel自定义异常,你用过几种?
Spring Cloud Alibaba Sentinel 是目前主流并开源的流量控制和系统保护组件,它提供了强大的限流.熔断.热点限流.授权限流和系统保护及监控等功能.使用它可以轻松的保护我们微服务 ...