如何用微服务重构应用程序
在决定使用微服务之后,为了将微服务付诸实践,也许你已经开始重构你的应用程序或把重构工作列入了待办事项清单。
无论是哪种情况,如果这是你第一次重构应用程序,那么您和您的团队必将在某个时刻面临一个显而易见的问题:如何重构应用程序以实现微服务?
这也正是这篇文章要思考和探讨的。
重构基础
在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。
重构=重新设计
将一个单体式的应用程序重构为微服务,与重新设计一个基于微服务的应用程序, 有着本质区别。也许您更倾向于摒弃旧的应用程序(特别是面对杂乱无序的旧应用程序,这些应用程序在补丁修改和加固补充方面带来了沉重的技术债负担),制定一套新的需求, 并从零开始创建一个全新的应用程序,直接在微服务级别工作。
正如Martin Fowler在这篇文章中所指出,在微服务级设计一个新的应用程序可能不是一个好主意。Fowler的分析中最重要的一点是,在移动到基于微服务的架构时,从现有的单体式应用程序开始可以真正发挥微服务的优势。(文章链接:https://martinfowler.com/bliki/MonolithFirst.html)
通过现有的单体式应用程序,您可能会清楚地了解各种组件如何协同工作,以及应用程序如何作为一个整体运行的。而令人惊奇的是,从单体式的应用程序开始,您可以更深入地了解微服务之间的界限。通过观察他们是如何协作的,您可以更容易地看到,某个微服务能够独立于另一个微服务。
重构并不通用
对于重构,不存在一种适用一切的通用性方法,您所做的设计选择,从整体架构到代码级,都应考虑到应用程序的功能、运行条件以及开发平台和编程语言等因素。例如,您可能需要考虑代码打包—如果您正在使用Java,则可能涉及从大型企业应用程序存档(EAR)文件(每个文件可能包含多个Web应用程序存档(WAR)软件包)转移到单独的 WAR文件。
一般重构策略
以上是我们介绍的高层次考虑因素,现在让我们来看看重构的实现策略。对于现有的单体式应用程序进行重构,有三种基本方法。
增量
通过此策略,您可以逐个重构应用程序。随着时间的推移,这些组件通常是大规模的服务或相关服务组。要成功做到这一点,首先需要确立应用程序中的大范围边界,然后针对这些边界定义的单元进行重构,一次一个单元。您将持续不断地把每个大区域移动到微服务中,直到最终没有原始应用程序为止。
大变小
“大到小”策略在许多方面都是对增量重构基本主题的变体。然而,在大到小的重构中,您首先要将应用程序重构为单独的、大规模的、“粗粒度的”(使用Fowler的术语)块,然后逐渐将它们分解成更小的单元,直到整个应用程序被重构为真正的微服务。
此策略的主要优点是,它允许您稳定重构单元之间的交互,然后将它们分解为下一级,并在您开始下一轮重构之前,让您更清晰地了解较低层服务之间的边界和交互。
批量替换
通过批发更换,您可以一次性重构整个应用程序,直接从单体式转移到一组微服务器。它的优势在于,它允许您从顶层架构下进行重新设计,为重构作准备。虽然这一策略与微服务不一样,但它确实与微服务有着相同的风险,特别是当它涉及到广泛的重新设计时。
重构中的基本步骤
那么,将一个单体式应用程序重构为微服务的基本步骤是什么?有几种方法可以打破这个流程,但对于大多数重构项目来说,以下五个步骤是(或应该)通用的。
(1)准备工作
迄今为止我们所讨论的大部分是准备工作。要牢记的要点是,在重构现有的单体式应用程序之前,大架构以及要进行重构的基于微服务的版本的功能应已就绪。在重构时试图修复功能失调的应用程序,这只会使两项工作更加困难。
(2)设计:微服务域
在大规模、应用广泛的架构之下,您需要在重构之前制定(并应用)一些设计决策。特别是,您需要考虑哪种微服务组织形式最适合您的应用程序。组织微服务最自然的方式通常是进入基于通用功能、使用或资源访问的域:
-
功能域。相同功能域内的微服务执行一组相关功能,或具有相关性的职责。例如,购物车和结帐服务可以包含在相同的功能域中,而库存管理服务将占用另一个域。
-
使用域。如果您通过使用破解您的微服务器,那么每个域将围绕一个用例,或者更常见的,一组相互关联的用例。用例通常围绕用户(个人或其他应用程序)采取的一组相关行动,例如选择购买商品或输入付款信息。
-
资源域。访问相关资源组(如数据库、存储或外部设备)的微服务也可以形成不同的域。这些微服务通常会处理这些资源与所有其他域和服务的交互。
请注意,在给定的应用程序中,三种组织形式都可能都存在。如果有一个总体规则,那么简单地说,您应该在它们最适合的时间和地点应用它们。
(3)设计:基础设施和部署
此步骤非常重要,但却很容易被视作事后再来考虑的问题。您正在将一个应用程序转换为一种非常动态的微服务群,通常在容器或虚拟机中,并由可能由多个应用程序组合的基础架构部署、编排和监控。此基础架构是您应用程序架构的一部分; 它可能(并且可能会)接管以前在单体式应用程序中由高级架构处理的一些职责。
(4)重构
这是您将应用程序代码实际重构为微服务的一个重点。确立微服务边界,识别每个微服务候选项的依赖关系,在代码和单元架构级别上进行必要的更改,以便它们可以作为独立的微服务来容纳,并将其封装在容器或VM中。这不会是一个没有问题的过程,因为在主要应用程序的规模上重写代码非常不易,但是,只要准备充分,您遇到的问题就更有可能局限于现有的代码问题。
(5)测试
当您进行测试时,您需要在基础架构(包括容器/ VM部署和资源使用)级别以及整体应用级别上查找微服务和微服务交互级别的问题。通过使用基于微服务的应用程序,所有这些都很重要,每个应用程序都可能需要自己的一套测试/监视工具和资源。当您发现问题时,了解什么级别的问题应该被处理是非常重要的。
结论
对微服务的重构可能需要下些功夫,但这并不难。只要您能做好准备,并清楚地了解所涉及的问题,您就能有效地重构您的微服务应用,而无需从头到尾重新设计。