Chris Richardson微服务翻译:重构单体服务为微服务
Chris Richardson 微服务系列翻译全7篇链接:
- 微服务介绍
- 构建微服务之使用API网关
- 构建微服务之微服务架构的进程通讯
- 微服务架构中的服务发现
- 微服务之事件驱动的数据管理
- 微服务部署
- 重构单体应用为微服务(本文)
原文链接: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。每提取一个模块,就向着微服务的方向又迈进了一步。随着时间推移,单体应用将会逐渐消失,你也会拥有更多的微服务。
总结
将单体应用迁移到微服务的过程是应用现代化的一种形式。并不需要从头重写代码,而是渐进式地将应用重构为一组微服务。其中有三种策略:使用微服务实现新功能;将展示层从业务逻辑层、数据访问层中拆分;将单体应用内的模块转化为微服务。随着时间的推移,微服务的数量将会增加,从而提升团队的敏捷和效率。
Chris Richardson微服务翻译:重构单体服务为微服务的更多相关文章
- Chris Richardson微服务翻译:微服务之事件驱动的数据管理
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理(本文) 微服 ...
- Chris Richardson微服务翻译:微服务架构中的服务发现
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...
- Chris Richardson微服务翻译:构建微服务之微服务架构的进程通讯
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯(本文) 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...
- Chris Richardson微服务翻译:构建微服务之使用API网关
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关(本文) 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...
- Chris Richardson微服务翻译:微服务介绍
作者简介:Chris Richardson,世界著名的软件架构师,经典著作<POJOS IN ACTION>的作者,cloudfoundry.com 的创始人 微服务目前正受到大量的关注, ...
- Chris Richardson微服务翻译:微服务部署
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服务部署( ...
- 【转】「Chris Richardson 微服务系列」微服务架构的优势与不足
Posted on 2016年5月4日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战. 作者介绍:Chris Ric ...
- 【CHRIS RICHARDSON 微服务系列】事件驱动的数据管理-5
编者的话 |本文来自 Nginx 官方博客,是「Chris Richardson 微服务」系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模 ...
- 【CHRIS RICHARDSON 微服务系列】微服务架构中的进程间通信-3
编者的话 |本文来自 Nginx 官方博客,是微服务系列文章的第三篇,在第一篇文章中介绍了微服务架构模式,与单体模式进行了比较,并且讨论了使用微服务架构的优缺点.第二篇描述了采用微服务架构的应用客户端 ...
随机推荐
- RedHat Linux AS4 DNS 配置
RedHat Linux AS4 DNS配置 检查当前系统中安装 DNS功能组件bind情况 [root@svr01 /]# rpm -qa|grep bind* ypbind-1.17.2 ...
- wget 下载百度网盘文件
上传文件到服务器,有许多种方法,罗列一下我用过的 xftps之类的工具 rz tz命令 git 上传到码云 通过wget方式,上传文件到百度网盘,七牛云等只要支持wget方式下载即可 下面介绍一下怎么 ...
- js、jquery实现模糊搜索功能
模糊搜索功能在工作中应用广泛,并且很实用,自己写了一个方法,以后用到的时候可以直接拿来用了! 实现的搜索功能: 1. 可以匹配输入的字符串找出列表中匹配的项,列表框的高度跟随搜索出的列表项的多少改变 ...
- AJAX扩展-POST传递参数并跳转页面
拓展的代码: 这段代码的原理是创建一个表单,所有args都创建一个隐藏的input,用post方法把这些参数传递过去 注意form表单一定要加载到页面中,即下面代码中标红的部分,不然参数是无法被传递的 ...
- Not++规范格式(格式化)
Notepad++功能比Windows中的 Notepad(记事本)强大,除了可以用来制作一般的纯文字说明文件,也十分适合编写计算机程序代码.Notepad++ 有语法高亮度显示和语法折叠功能,并且支 ...
- web前端学习就这9个阶段,你属于哪个阶段?
第一阶段:HTML+CSS: HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础:Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMAsc ...
- Java Web Session设置
一.前言 在做 java web项目时,我们很多时候都要用到 Session,那么我就简单的写一下 Session 的写法. 二.代码实现 Servlet Session 的设置 package co ...
- Spark术语
1.resilient distributed dataset (RDD) The core programming abstraction in Spark, consisting of a fau ...
- 1.移植uboot-分析uboot启动流程(详解)
本节总结: uboot启动流程如下: 1)设置CPU为管理模式 2)关看门狗 3)关中断 4)设置时钟频率 (FCLK:HCLK:PCLK=1:2:4,FCLK=120Mhz) 5)关mmu,初始 ...
- 查看当前支持的shell,echo -e相关转义符,一个简单shell脚本,dos2unix命令把windows格式转为Linux格式
/etc/shells [root@localhost ~]# more /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bi ...