Chris Richardson微服务翻译:重构单体服务为微服务

Chris Richardson 微服务系列翻译全7篇链接:

原文链接:Refactoring a Monolith into Microservices


微服务重构的概述

将单体应用转化为微服务是应用现代化的一种形式,数十年来开发者们一直致力于此。因此,将应用重构为微服务时,我们可以借鉴其中的一些经验。

首先不要大规模地重写代码,不要集中所有力量从头构建一个新的微服务应用,这中方式听起来很吸引人,但是会有极大的风险,有可能以失败告终。正如 Martin Fowler 所言:

the only thing a Big Bang rewrite guarantees is a Big Bang!

相反,我们应该渐进式的重构单体应用。逐步构建由微服务组成的新应用,与单体应用一起运行;随着时间的推移,单体应用实现的功能会不断收缩,直至完全消失或者转变为另一个微服务。这一方法虽然充满挑战,但风险远小于大规模重写代码。

Martin Fowler 将这一策略称为“杀手应用”。这一名称源自热带雨林中的杀手藤。杀手藤附生于大树的周围,企图得到树冠处的阳光,最后树木死后,留下树状的藤蔓。应用现代化也遵循这一方式。我们将围绕着遗留应用构建由一些列微服务组成的新应用,直至遗留应用消失。

接下来了解不同的实现策略。

策略一:停止挖坑

如果发现自己掉入坑里,应该马上停止挖坑。一旦单体应用变的难以管理,你应该停止让单体应用继续变的庞大,实现新功能时,不应该往单体应用中添加新的代码。相反的,而是把新代码放到独立的微服务中。下图展示了此方法的系统架构:

除了新服务和遗留的单体应用,这个系统还包括其他两个组件:第一个是请求路由,用来处理 HTTP 请求,与之前文章中所说的 API 网关类似。路由将与新功能相对应的请求发送到新服务上去,将遗留请求发送到已有的单体应用上去。

另一组件是胶水代码,用来集成微服务与单体应用。微服务很少独立存在,通常需要访问单体应用拥有的数据。胶水代码存在于单体应用或微服务中,或者两者兼有,用来负责数据的集成。微服务使用胶水代码来对单体应用的数据进行读写。

微服务可以通过以下三种方式来访问单体应用的数据:

  • 调用单体应用提供的 API
  • 直接访问单体应用的数据库
  • 维护一份数据副本,与单体应用的数据库保持同步

胶水代码也被称为 anti-corruption layer。因为胶水代码能防止拥有全新领域模型的服务被遗留单体应用的领域模型所污染。胶水代码在两种不同的模型间进行转换。anti-corruption layer 这一术语来自 Eric Evans 撰写的 Domain Driven Design 中。要想远离单体应用的泥淖,开发 anti-corruption layer 是必不可少的。

以轻量级微服务的方式实现新功能有许多优点:它能够防止单体应用变的不可管理。微服务能够独立开发、部署和扩展。你可以通过创建新的服务来体会到微服务架构的好处。

然而,这一方法并没有解决单体应用的问题。要想解决这些问题,需要拆分单体应用。让我们看一下拆分的策略。

策略二:前后端分离

缩小单体应用的策略之一是将展示层从业务逻辑层和数据访问层中拆分出来。典型的企业应用包括一下三种组件:

  • 展示层:处理 HTTP 请求并实现基于 REST API 或 HTML 的 Web UI。在一个-
    用户界面复杂的应用中,展示层通常包含了大量的代码
  • 业务逻辑层:应用的核心,实现了业务逻辑
  • 数据访问层:访问数据库和消息代理等基础架构组件

通常展示层对于业务逻辑层与数据访问层来讲,彼此有着清晰的划分。业务层由若干个 API 组成,内部封装了业务逻辑。这些 API 是将单体应用拆分为两个更小应用的分界线。一个应用包含表示层,另一个应用包含业务逻辑层和数据访问层。拆分后,展示逻辑的应用向业务逻辑的应用发起远程调用。下图展示了重构前后的构架:

以这种方式拆分单体应用有两大好处:1)它使得两个应用可以独立的开发、部署和扩展。尤其是,它使得展示层的开发者能够快速迭代用户界面,轻松的进行 AB 测试。2)暴露了可被其他服务调用的 API
这种策略也只是部分解决方案,很有可能两个应用会变成难以管理的单体应用。这时需要使用第三种策略来消除剩余的单体应用。

策略三:提取微服务

重构的第三个策略是将单体中现有的模块变成独立的微服务,每次提取模块为微服务时,单体就会缩小,一旦转化了足够多的模块,单体应用将不再是问题,要么消息,要么变成另一个微服务。

为需要转化为微服务的模块设置优先级

大型、复杂的单体应用由数十甚至数百个模块组成,所有模块都是可提取的。弄清楚哪个模块需要首先被提取往往是挑战性的问题。一个好的方式是先选择易于提取的模块,这将给开发者熟悉微服务以及积累提取经验。之后可以提取哪些可以带来最大收益的模块。

将模块转变为微服务通常需要一定时间,一般会根据获得收益的大小来给模块排序。通常转换经常变化的模块带来的收益也最大。一旦把一个模块转换为微服务,就可以独立开发、部署它了,从而加快了开发速度。

提取那些对资源有独特需求的模块也会带来很多好处。例如,把需要内存数据库的模块转化为微服务,就能部署在大内存的主机上。同样的,将实现计算密集型算法的模块提取出来也是值得的,该微服务可以部署在拥有多个 CPU 的主机上。这种方式使得应用更容易扩展。

当决定哪些模块需要提取时,找出现有粗粒度的边界(即分界线)也大有裨益。这会使模块转化为微服务更加简单、省力。例如:一个只通过异步消息与其他部分通信的模块,转化为微服务是更简单的。

如何提取模块

提取模块的第一步是确定模块和单体应用的接口粒度。单体应用和微服务需要访问彼此的数据,更像是双向 API,模块和应用其它部分之间存在着互相依赖,因此实现这些 API 一般充满挑战。重构时使用领域模型来实现业务逻辑变的尤为困难,一般需要大的代码改动才能打破这些依赖。

一旦实现粗粒度的接口,就可以将模块转化为独立的微服务。要做到这一点,必须能够让单体应用和微服务通过 API 通信。 下图展示了重构前、重构中和重构后的不同架构:

模块 Z 是要被提取的模块,它使用到模块 Y ,同时它的组件被模块 X 使用。重构的第一步就是定义一组粗粒度 API,第一个接口是模块 X 调用模块 Z 的 接口。第二个接口是模块 Z 调用模块 Y的接口。

重构的第二步是把模块转变为独立的微服务。对内和对外接口通过 IPC 机制实现,开发人员可能只需要将模块 Z 与微服务支撑框架(Microservice Chassis framework)组合起来构建微服务。

一旦将模块提取完毕,你就拥有了一个新的微服务,它能够独立于单体应用和其它微服务进行开发、部署和扩展。如果想重写微服务的代码,集成微服务和单体应用的 API 会成为这两个领域模型之间的 anti-corruption layer。每提取一个模块,就向着微服务的方向又迈进了一步。随着时间推移,单体应用将会逐渐消失,你也会拥有更多的微服务。

总结

将单体应用迁移到微服务的过程是应用现代化的一种形式。并不需要从头重写代码,而是渐进式地将应用重构为一组微服务。其中有三种策略:使用微服务实现新功能;将展示层从业务逻辑层、数据访问层中拆分;将单体应用内的模块转化为微服务。随着时间的推移,微服务的数量将会增加,从而提升团队的敏捷和效率。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容