写点什么

微服务划分的模式与反模式

  • 2020-04-26
  • 本文字数:4168 字

    阅读完需:约 14 分钟

微服务划分的模式与反模式

微服务划分模式

虽然服务是逐步被拆分出来的,随着业务的演进,在某一时刻,可能需要我们重新审视服务划分得是否合理。本节向大家推荐两种服务划分的方法,首先介绍如何选择服务划分的方法。

基于业务复杂度选择服务划分方法

根据业务复杂度划分服务,如图 2-4 所示。当业务复杂度足够高的时候,应该基于领域驱动划分服务,而领域驱动本身足够复杂,很多概念比较抽象,应用范围并不是特别广泛,所以当业务复杂度较低时,可以选择基于数据驱动划分服务。数据驱动更容易理解和上手。也就是说,除非业务复杂度非常高,否则应该优先以数据驱动划分服务。这里的业务复杂度专指业务逻辑,而非数据量、并发量等相关复杂度。



图 2-4 根据业务复杂度划分服务


在做出选择的时候,还有一个参考指标是,团队以前是否已经基于领域驱动开发业务。也就是说,如果产品已经基于领域驱动开发了一段时间,团队具备了领域驱动开发的能力,那么推荐继续选择领域驱动划分服务。如果是一个全新的产品,则可以灵活选择。


选择服务划分的方法时要重点考虑如下条件。


  • 业务复杂度。

  • 团队对领域驱动的熟悉程度。


基于数据驱动划分服务


现比较粗糙的界面,进行内部讨论;不断迭代此环节,直到满意为止。


(2)抽象数据结构。根据需求总结 Use Case,协助分析需求,从中抽象数据结构。


(3)划分服务。分析数据结构,识别服务——服务应该满足高内聚、低耦合、单一职责等特征。


(4)确定服务调用关系。先分析出主要流程,根据请求需要调用的服务确定服务调用关系。如果存在问题,则需要回到(1)重新开始。


(5)业务流程验证。重新回到 User Story,以服务为粒度实现时序图,注意此阶段重点是验证服务划分是否合适,要关注如下问题。


  • 一次更新操作如果要跨越更多服务,那么一致性的要求是什么。

  • 跨服务查询时,是否要做关联查询,一个服务内是否能解决问题。

  • 性能是否能满足要求。

  • 成本是否满足要求。

  • (6)持续优化。


基于领域驱动划分服务


领域驱动是一个自上而下的架构设计方法,通过和领域专家建立统一的语言,不断交流,确定关键业务场景,逐步确定边界上下文。领域驱动更强调业务实现效果,认为自下而上的设计可能会导致技术人员不能更好地理解业务方向,进而偏离业务目标。


通常基于领域驱动划分服务的步骤如下。


(1)通过模型和领域专家建立统一语言。建立统一语言是为了更深入地理解需求。通用语言尽量以业务语言为主,而非技术语言;通用语言和代码一样,需要不断地重构。


(2)业务分析。确定核心的业务流程,然后逐步扩展到全部。最好通过工具呈现比较粗糙的界面,供内部讨论。


(3)寻找聚合。显式地定义领域模型的边界。最近比较热门的事件风暴,是一种基于领域驱动分析业务、划分服务的方法。


事件风暴就是把所有的关键参与者都召集到一个很宽敞的屋子里来开会,并且使用便利贴来描述系统中发生的事情,如图 2-5 所示。



图 2-5 事件风暴


  • 用桔黄色的便利贴代表领域事件,在上面用一句话描述曾经发生过什么事情。

  • 用蓝色的便利贴代表命令。命令的发起者可能是人,也可能是注入系统中的外部事件,或者定时器等。

  • 用黄色的便利贴代表聚合。聚合是一组相关领域对象的集合,高内聚、低耦合是其基本要求,聚合内还要保证数据一致性。


(4)确定服务调用关系。先分析出主要流程,根据一次请求需要调用的服务来确定服务调用关系。如果存在水平划分,则需要根据服务依赖原则确定关系。如果存在问题,则需要回到(1)重新开始。


(5)业务流程验证。以服务为粒度实现时序图,注意此阶段重点是要验证服务划分是否合适,主要关注如下问题。


  • 一次更新操作如果要跨越更多服务,那么一致性的要求是什么。

  • 跨服务查询时,是否要做关联查询,一个服务内是否能解决问题。

  • 性能是否能满足要求。

  • 成本是否满足要求。


(6)持续优化。


从已有单体架构中逐步划分服务


在大多数场景下,并非从开始阶段就采用微服务架构,而是随着业务不断发展,从最初的单体架构中逐步拆分服务。下面描述了从一个单体架构逐步拆分的步骤。


(1)所有微服务成功的故事都是从一个单体架构太大,需要被拆散开始的,如图 2-6 所示。我们应该从单体架构开始,当系统规模足够大、团队人数足够多时,再逐步拆分服务,通常前后端分离是拆分的第一步。



图 2-6 从已有架构逐步拆分服务(一)


(2)提取公共基础服务,如单点登录。拆分可以遵循逻辑分离和物理分离两种方法。另外随着系统压力的增加,可能会用到消息中间件、分布式缓存等服务。


(3)不断地从老系统中抽象出服务,垂直划分优先,如图 2-7 所示。



图 2-7 从已有架构逐步拆分服务(二)


(4)当业务越来越复杂的时候,API Gateway 做了太多的事情,会成为一个瓶颈点,服务之间的依赖关系也会变得越来越复杂,此时,需要适当地进行水平切分,如图 2-8 所示。



图 2-8 从已有架构逐步拆分服务(三)


微服务拆分策略


当不断从单体架构中抽象服务的时候,哪些服务优先被拆分,哪些服务不需要被拆分?以下几个策略可以帮助解决拆分中的这些问题。


  • 比较独立的新业务优先采用微服务架构。从成本角度考虑,新业务采用新的架构是最合理的,因为这样做对老业务的影响最小。

  • 优先抽象通用服务。因为通常通用服务的边界比较明显,耦合度低,比较容易分离。

  • 优先抽象比较容易识别的、边界比较明显的服务。如果原有包结构比较清晰,可以基于原有包结构中有明显边界的、比较完整的业务进行划分,这是从成本角度考虑。如果已经基于单体架构开发了一段时间,对业务的理解程度已经非常高,那么开发及架构人员能够比较容易地提炼出一些边界比较明显的服务。

  • 优先抽象核心服务。因为微服务的开发及运维成本比较高,并不是所有的地方都需要划分很小的粒度。往往一些比较边缘的运营、管理的系统甚至不会考虑拆分。另外,随着时间的推移,有一些业务可能会发生改变,因此应该先抽象出核心服务。

  • 优先抽象具有独立属性的服务。应根据功能的变更频率、资源占用、技术栈等属性划分服务。

  • 采用绞杀者模式,在遗留系统外围,随着时间的推移,让新的服务逐渐“绞杀”老的系统。在这种情况下,复杂度往往体现在如何灰度发布、迁移数据,以及如何保障服务不中断,后面的章节会详细描述。


如何衡量服务划分的合理性


每个产品在实施微服务架构最初的动力都不一样,目标也有所区别,所以判断是否划分合理,首先要看是否达成了目标。其次,可以参考以下几种衡量方式。每种衡量方式不能单独作为一个判断标准,需要综合考虑。


  • 一个小功能的修改从需求到上线需要多长时间?正常情况下的微服务架构交付周期应该是以天为单位的。如果一个小功能的修改需要几周到几个月的时间,可能意味着服务划分粒度过大,存在太多的冲突,要等待合并代码。

  • 大多数功能修改是否可以在一个服务内完成?如果经常需要跨服务团队的联合开发组才能完成一个新功能的开发或者旧功能的修改,则说明服务划分存在问题。

  • 是否要频繁修改接口?频繁修改接口有可能是接口设计不合理导致的,也有可能是服务划分的问题导致的,说明服务之间的边界并不是特别明确和稳定。

  • 响应时间是否能满足要求?在某些追求极致性能的场景中,对响应时间要求较高,服务划分的层次太多、粒度太小都可能导致响应时间不能满足要求。

  • 是否存在大量的跨服务更新?是否存在大量的跨服务的关联查询?出现这两个问题,可能是因为划分不合理。

微服务划分反模式

前面我们介绍了如何划分服务,在此之上,我们希望通过微服务划分的反模式来帮助大家少走弯路。


根据代码行数划分服务


代码规模太大会导致沟通效率、交付效率低下,耦合度高,以及比较笨重。代码规模可以作为一个参考,但是不能作为一个绝对标准,微服务架构中存在一个“大服务”是很正常的。基于代码行数拆分服务很难衡量服务的完整性,容易导向更小的拆分粒度,引起不必要的复杂度。


划分粒度越小越好


服务的大小并不是特别重要,可以根据团队规模、代码规模、业务复杂度、技术领域、重要程度、成本等因素综合考虑。关于服务粒度的大小,业界并没有统一标准,也很难衡量,最接近的衡量标准是研发团队规模。粒度小意味着更高的维护成本。后端管理、辅助系统通常粒度较大。


一次性划分服务


拆分服务有如下两种方式。


第一种,先拆分业务代码再拆分数据库。如图 2-9 所示,数据库并没有拆分,只是从单体中抽象出部分服务。



图 2-9 先拆分业务代码再拆分数据库


第二种,业务代码和数据库同步拆分。如图 2-10 所示,部分业务服务被拆分出来的同时,数据库也被同步拆分出来。



图 2-10 业务代码和数据库同步拆分


采用第二种方式拆分服务时,根据服务将数据库彻底拆分为多个独立的数据库,每个服务独享数据库服务,服务之间只能通过接口调用。这看起来非常美好,但需要为此做大量的数据迁移。当业务处于初期,需求不是非常确定,开发人员对业务理解不是特别透彻的时候,可能拆分后发现拆分得并不合理,只能再进行合并,又要进行一次数据迁移。相对来说,业务代码拆分成本更低,而数据迁移的成本更高,频繁、大量的数据迁移并不可取。


更好的做法是把第一种方式作为过渡阶段,当业务逐步稳定后再彻底进行数据迁移。注意,处于过渡阶段时数据库并没有彻底分离,一切依赖都通过接口访问。但是这只是口头上的约定,对于业务开发人员直接在数据库中进行关联查询。需要通过 Code Review 的方式避免。


服务划分是一个长期的过程,需要积累大量的领域知识,以此来理解核心流程。最好是和领域专家一起组成联合团队,在理解核心问题的情况下,持续拆分服务并验证拆分合理性,随着时间的推移,还可以重新划分。可见,服务拆分是一个持续性的过程。


服务划分一旦完成,不能改变


由于业务的不断变化,以及开发人员对领域知识和其他影响因素的理解等问题,很难一次性做出一个完美的解决方案。通常在划分后会发现,某个问题是不可忍受的,例如划分后导致响应时间降低,增加了更多的成本,有可能需要重新合并服务;由于业务的变化,原本的依赖关系发生了变化,有可能面临需要重新划分服务等类似的问题。


**先实施组件化,再实施微服务架构 v


很多技术人员试图先通过组件化逐步过渡到微服务架构,这是一种错误的思路。微服务架构划分更强调业务领域的完整性,因此垂直划分优先,而组件化往往通过抽象出稳定的部分形成组件共享,对调用次数和依赖关系并不强调。因此,组件化之后再转化到微服务架构的方式,通常是错误的。


本文转载自技术琐话公众号。


原文链接:https://mp.weixin.qq.com/s/EM98g6EdM2tVzUGiuuSBow


2020-04-26 16:442067

评论

发布
暂无评论
发现更多内容

深入研究:亚马逊amazon商品详情API接口Python攻略

tbapi

亚马逊API 亚马逊商品详情API 亚马逊商品列表接口 亚马逊数据采集

微信小游戏开发的技术框架

北京木奇移动技术有限公司

软件外包公司 游戏外包公司 游戏开发公司

快手12篇论文入选CVPR 2025!

快手技术

人工智能 大模型 快手 学术成果

视觉与图像识别自动化测试 | 图像识别

测试人

人工智能

MyCat应用实战:分布式数据库中间件的实践与优化(篇幅一)

肖哥弹架构

Java mycat

目前黑龙江对等保三级要求是什么?

等保测评

真实场景文档理解:字节发布的WildDoc基准数据集向OCR提出了什么挑战?

合合技术团队

算法 人工智能’ #大数据

轻量级防护软件,火绒安全软件下载,病毒查杀、防护中心、访问控制,拦截黑客入侵、网络钓鱼攻击

小焱

杀毒软件 防护软件 火绒 杀毒

为AI推理需求的未来做准备:第二部分

ScaleFlux

狄耐克脑电波交互事业部走访四大实验室,共探脑电波交互技术新局

新消费日报

开源夜莺支持MySQL数据源,更方便做业务指标监控了

巴辉特

夜莺监控 运维监控 开源监控

多格式文件在线预览,提升移动设备文件处理效率与体验

HarmonyOS SDK

harmoyos

微信小程序上线后的运维

北京木奇移动技术有限公司

微信小游戏 软件外包公司 游戏外包公司

如何利用YashanDB实现业务数据的高效管理?

数据库砖家

Go 语言中如何操作二维码?

左诗右码

大数据-09-HDFS集群 JavaClient 代码上手实战!详细附代码 安装依赖 上传下载文件 扫描列表 PUT GET 进度条显示

武子康

大数据 hdfs mapreduce hive

综合治理系统(源码+文档+讲解+演示)

深圳亥时科技

dbops 助力 GreatSQL MGR架构安装部署

GreatSQL

OCR 识别质量如何影响 RAG 系统的性能?有何解决办法?

Baihai IDP

AI OCR LLM Baihai IDP 检索增强生成

为AI推理需求的未来做准备:第一部分

ScaleFlux

中烟创新数字档案:开启烟草行业“智”理新动能

中烟创新

HarmonyOS运动开发:如何选择并上传运动记录

王二蛋和他的张大花

Unity开发游戏的技术框架

北京木奇移动技术有限公司

游戏开发 软件外包公司 游戏外包

如何利用YashanDB数据库加强数据分析能力

数据库砖家

什么是WMS系统?WMS仓库管理系统到底具备哪些功能?

积木链小链

数字化转型 wms 仓库管理

Flutter驱动的小程序容器化:SuperApp开发效率革命

xuyinyin

当AI开始辅助编程,度量代码还有意义吗?

思码逸研发效能

研发管理 研发效能 代码 效能度量 思码逸

微信小游戏的运营

北京木奇移动技术有限公司

游戏开发 游戏运营 游戏外包公司

哈尔滨企业如何做信息安全等级保护工作?

等保测评

深入研究:亚马逊amazon商品列表API接口Python攻略

tbapi

亚马逊API 亚马逊商品列表接口 亚马逊商品详情接口 亚马逊数据采集

macOS Tahoe 26 让 Mac 更强大、更高效、更智能

柠檬与橘子

微服务划分的模式与反模式_服务革新_技术琐话_InfoQ精选文章