从分层架构到微服务架构(五)之服务化架构

2023-11-09

《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章,这里不会事无巨细地介绍所有的细节,而是会挑选其中关键内容,更多详情请阅读原书。

往期精彩

前言

从本文开始,我们进入了《从分层架构到微服务架构》系列中分布式架构的介绍,本文要介绍的是服务化架构Service-Based Architecture,SBA)。

SBA 可以看成是单体架构和微服务架构之间的一个折中方案,它也是按照业务领域进行服务划分,但服务划分的粒度相比微服务要更粗。SBA 与微服务架构一大不同是,它允许各个服务间共享同一个数据库实例,这也使得 SBA 在架构上既有单体架构的特点,也有分布式架构的特点,显得更加的灵活。因此,从单体架构演进到 SBA,会比直接演进到微服务架构更加容易

架构视图

基础视图

SBA 的基础架构视图分成 3 部分:

  • User Interface,作为系统的接入口,接收客户端的请求,并转发到业务服务。。
  • Domain Services,业务服务按照领域进行划分,分开部署、业务独立。
  • 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 层协调会各个组件依次完成如下的几个业务流程 :

  1. 调用订单组件,完成订单ID、订单内容的生成。
  2. 调用支付组件,完成用户的扣款。
  3. 调用库存组件,更新商品的库存数量。

因为这些业务流程都是在同一个服务内完成,当其中的某个流程异常后,我们很容易通过数据库的 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 虽然支持服务实例扩容,但是更粗的服务粒度会导致扩容的性价比并不高,因此 ScalabilityElasticity 得分不高。

ScalabilityElasticity的差异:

  • Scalability 通常指软件系统在不中断业务的前提下,通过 scale-up 或 scale-out 等手段来应对更高业务负载,强调的是软件系统应对高负载的能力。
  • Elasticity 通常指硬件系统能够根据实际的业务负载情况,适时增加或减少硬件资源,强调的是硬件资源的高效利用。

总结

如果你打算从单体架构演进到分布式架构,SBA 会是一个不错的选择

  • 相比单体架构,SBA 按照业务进行服务拆分,在业务解耦、开发流程敏捷等方面有着明显的优势。
  • 相比其他分布式架构,SBA 有着更粗的服务粒度,因此也得以减少了服务间的远程调用、网络带宽消耗,受网络故障的影响更小。
  • 服务间共享数据库使得 SBA 支持 ACID 事务,在数据一致性方面具有良好的表现,但我们还是应该尽量按照业务进行分表,避免出现严重的数据耦合。
  • 在架构评分上,SBA 各方面评分都不错,没有明显的缺点,是典型的“六边形战士”。

参考

  1. Fundamentals of Software Architecture (Chapter 13. Service-Based Architecture Style), Mark Richards, Neal Ford
  2. Service-Based Architecture as an Alternative to Microservice Architecture, Matt Fletcher
  3. What is the difference between scalability and elasticity?, stackoverflow

更多文章请关注微信公众号:元闰子的邀请

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从分层架构到微服务架构(五)之服务化架构 的相关文章

随机推荐

  • YAML学习笔记

    一 YAML概念 在运维日常工作中又很多遇到yaml 例如写ansible的playbook 利用yaml来定义创建各应用及服务 1 1 概念 YAML 发音 j m l 是一个类似 XML JSON 的数据序列化语言 YAML是专门用来写
  • HTTP Status 400 – Bad Request

    采用SpringMVC架构 写的一个简单的form请求 结果出错了 报错信息如下 Type Status Report Description The server cannot or will not process the reques
  • 计算机启动过程详解

    打开电源启动机器几乎是电脑爱好者每天必做的事情 面对屏幕上出现的一幅幅启动画面 我们一点儿也不会感到陌生 但是 计算机在显示这些启动画面时都做了些什么工作呢 相信有的朋友还不是很清楚 本文就来介绍一下从打开电源到出现Windows的蓝天白云
  • opencv源码阅读之——iOS的两条接口UIImageToMat()和MatToUIImage()

    转自 https www cnblogs com panxiaochun p 5387743 html 本文为作者原创 未经允许不得转载 原文由作者发表在博客园 http www cnblogs com panxiaochun p 5387
  • 小程序微信支付申请与配置完整版操作流程

    小程序微信支付申请与配置完整版操作流程 一 申请小程序微信支付 微信支付申请分为两种情况 情况一 申请新的微信支付商户号 情况二 绑定已有微信支付商户号 注意 申请微信支付的小程序账户需要进行微信认证 注册主体为个人的小程序目前暂不支持微信
  • Excel转CSV格式

    注意 CSV文件导出来的 可以理解为 就是一个 普通的文件 但至于使用什么样的软件打开就是另一马事了 比如Excel打开后 出来 自动过滤了数字前面的0 这玩意程序控制不到 那是Excel的事情 CSV不是Excel文件切记 只不过用表格软
  • Cuda 11/10的Dockerfile

    说明 如果NVIDIA显卡不满足要求 请修改dockerfile文件配置要求或慎重使用 关于dockerfile使用请参考我的博客文章 https blog csdn net weixin 41194129 category 1021002
  • 期中总结(码猿周六下午)

    期中总结 这半个学期我们第一二节课考了试 但是 第一次 115分 第二次 110分 结果都很不理想 不过这也在情理之中 之后我们学习了 简单分治 前缀和 二分法 贪心加强 递推 但是实际上后面几题都听得云里雾里的 毕竟是基础不好 再加上码龄
  • 一元多项式求导 C语言

    设计函数求一元多项式的导数 注 x n n为整数 的一阶导数为nxn 1 输入格式 以指数递降方式输入多项式非零项系数和指数 绝对值均为不超过 1000 的整数 数字间以空格分隔 输出格式 以与输入相同的格式输出导数多项式非零项的系数和指数
  • 前端优秀插件网站汇总整理——轻松建站。。。

    1 Amaze Ui 妹子UI 中国首个html5跨屏前端框架 http amazeui org 2 WebUploader 一个简单的以HTML5为主 FLASH为辅的现代文件上传组件 http fex baidu com webuplo
  • <python爬虫之JS逆向实例-1>新浪网

    声明 本文只作学习研究 禁止用于非法用途 否则后果自负 如有侵犯了您的合法权益 请告知 我将及时更正 删除 谢谢 邮箱地址 lc1139411732 163 com 文章目录 一 项目准备 二 参数分析 三 静态调试 四 动态调试 五 堆栈
  • yml连接两个mysql数据库_SpringBoot 多数据源配置/连接两个数据库 (SpringBoot+Mysql+SqlServer)(亲测可用)...

    Boot项目原配Mysql数据库 业务需要加上sqlserver数据库 网上看了两天 趟了不少坑 其实网上帖子挺全的 我遇到的问题没有太多相关介绍 现在搞好后分享给大家 自己也做个记录 1 首先 依赖配置 按需配置重点是数据库jar包跟bo
  • 攻防世界-lottery

    得到flag要 9990000 通过抽奖的方式获得钱 基本要7个数字都相同 扫目录 依次点开 robots txt中有 git 用git下载 或者直接下载附件1 源码 然后打开api php API Application Programm
  • 使用selenium+Edge进行浏览器不显示图片操作(屏蔽图片)

    使用Edge不加载图片进行 from msedge selenium tools import Edge EdgeOptions Edge options EdgeOptions 很关键的一步 只有为True才能进行ADD Edge opt
  • LeetCode 1143. 最长公共子序列(C++)

    题目地址 力扣 题目难度 Medium 涉及知识点 动态规划 字符串匹配 分析 由于子序列不同于子串 子串必须要连续 而子序列可以不连续 假设最长子序列长度为k 那么我们如果要通过遍历的方法来暴力求解 其时间复杂度至少为O 这肯定是无法接受
  • 【华为OD机试 2023】最左侧冗余覆盖子串(C++ Java JavaScript Python)

    华为od机试题库 华为OD机试2022 2023 C Java JS Py https blog csdn net banxia frontend category 12225173 html 华为OD机试2023最新题库 更新中 C Ja
  • (fastjson)java 如何将String(字符串)与JSON互转

    一 导入依赖
  • Apple的示例SpeakHere不能运行解决

    From your error message Application windows are expected to have a root view controller at the end of application launch
  • 论文写作记录

    论文画图 在MATLAB中导出600dpi图像 导出设置dpi后 导出tif格式的图片 直接重命名为jpg格式
  • 从分层架构到微服务架构(五)之服务化架构

    从分层架构到微服务架构 是一系列介绍 Fundamentals of Software Architecture 中提到的8种架构模式的文章 这里不会事无巨细地介绍所有的细节 而是会挑选其中关键内容 更多详情请阅读原书 往期精彩 从分层架构