前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将单体应用重构为微服务

将单体应用重构为微服务

作者头像
用户1263954
发布2018-01-30 15:34:34
9390
发布2018-01-30 15:34:34
举报
文章被收录于专栏:IT技术精选文摘IT技术精选文摘

微服务重构概述

将单体应用程序转换为微服务的过程是应用程序现代化的一种形式。这是几十年来开发人员一直在做的事情。因此,在将应用程序重构为微服务时,有一些方法可以重用。

一个策略是不推荐“大面积”重写。那就是当您将所有的开发工作集中在从头开始构建新的基于微服务器的应用程序时。虽然听起来很吸引人,但它是非常危险的,可能会以失败告终。

您应该逐步重构单体应用程序,而不是大面积重写。您应该逐渐构建一个由微服务组成的新应用程序,并与您的单体应用程序一起运行。随着时间的推移,单体应用程序实现的功能量会缩小,直到它完全消失或者成为另一个微服务器。这种策略类似于在70公里/小时的高速公路上驾驶汽车,具有挑战性,但远远低于尝试大面积重写的风险。

应用现代化遵循相同的模式。我们将构建一个新的应用程序,包括围绕最终将会死亡的遗留应用程序的微服务。

我们来看看可以做到这一点的不同策略。

策略1 - 停止挖掘

洞法则说,每当你在一个洞里,你应该停止挖掘。 当您的单体应用程序变得难以管理时,这是很好的建议。 换句话说,你应该停止使整体更大。 这意味着当您实现新功能时,您不应该向整体添加更多的代码。 相反,这一策略的主要思想是将新代码放在独立的微服务器中。 下图显示了应用此方法后的系统架构。

除了新服务和传统的整体,还有另外两个组件。第一个是请求路由器,它处理传入的(HTTP)请求。它类似于前面文章中描述的API网关。请求路由器向新服务发送与新功能相对应的请求。它将遗留请求路由到单块。

另一个组件是粘合代码,它将服务与整体集成。一个服务很少孤立存在,并且通常需要访问该数据块所拥有的数据。位于整体和服务两者中的胶合代码负责数据集成。该服务使用胶合代码来读取和写入由单块所拥有的数据。

服务可以使用三种策略来访问单体数据:

调用由单体应用提供的远程API

直接访问该单体应用的数据库

维护自己的数据副本,与单体应用的数据库同步

胶合代码有时被称为反腐层。这是因为胶合代码阻止了具有自己的原始领域模型的服务,防止被遗留的单体应用领域模型的概念所污染。胶合代码在两种不同的模型之间转换。反腐层一词首先出现在埃里克·埃文斯(Eric Evans)的必读书“域驱动设计”(Domain Driven Design)中,并在白皮书中进行了改进。发展反腐层可能是一件不平凡的事情。但是,如果你想要从单一的地狱中发展出来,那么创建一个是必不可少的。

作为轻量级服务实现新功能有几个好处。 它阻止单体应用变得更加难以管理。 该服务可以独立于单体式开发,部署和扩展。 您将体验到您创建的每个新服务的微服务架构的优势。

然而,这种方法没有解决单体的问题。 要解决这些问题,您需要分解整体。 我们来看看这样做的策略。

策略2 - 拆分前端和后端

缩小单体应用程序的策略是从业务逻辑和数据访问层拆分表示层。典型的企业应用程序由至少三种不同类型的组件组成:

表示层 - 处理HTTP请求并实现(REST)API或基于HTML的Web UI的组件。在具有复杂的用户界面的应用程序中,表示层通常是大量的代码。

业务逻辑层 - 作为应用程序核心并实现业务规则的组件。

数据访问层 - 访问基础架构组件(如数据库和消息代理)的组件。

一方的展示层的逻辑和另一方的业务和数据访问逻辑之间通常有一个干净的分隔。业务层具有由一个或多个外观组成的粗粒度API,其封装了业务逻辑组件。这个API是一个天然的接缝,您可以沿着该接缝将整体拆分成两个较小的应用程序。一个应用程序包含表示层。另一个应用程序包含业务和数据访问逻辑。分割后,展示层逻辑应用程序对业务逻辑应用程序进行远程调用。下图显示了重构之前和之后的架构。

以这种方式拆分单体应用有两个主要优点。它使您能够独立于彼此开发,部署和扩展两个应用程序。特别地,它允许展现层开发人员在用户界面上快速迭代,并且更容易地执行A / B测试。这种方法的另一个好处是它暴露了一个可以由您开发的微服务器调用的远程API。

然而,这一策略只是部分解决方案。一个或两个应用程序很可能是一个无法管理的整体。您需要使用第三种策略来消除剩余的整体。

策略3 - 抽取服务

第三个重构策略是将庞大的现有模块转变为独立的微服务器。每次您提取一个模块并将其转换成服务时,整体就会缩小。一旦你已经转换了足够的模块,整体将不再是一个问题。要么它完全消失,要么变得足够小,只是另一种服务。

将哪些模块转换为服务的优先级

一个庞大的,复杂的单体应用程序由数十或数百个模块组成,所有模块都是抽取的候选者。弄清楚要先转换哪些模块往往具有挑战性。一个好的方法是从容易抽取的几个模块开始。这将给您一些通用的微服务和特别是抽取过程的经验。之后,您应该抽取那些能给您最大利益的模块。

将模块转换为服务通常是耗时的。你想按照你将收到的好处排列模块。抽取频繁更改的模块通常是有益的。一旦将模块转换为服务,您可以独立于单体来开发和部署模块,这将加速开发。

抽取具有与其他大容量的资源需求显著不同的模块也是有益的。例如,将具有内存中数据库的模块转换为服务是有用的,然后可以将其部署在具有大量内存的主机上。同样,抽取实现计算昂贵算法的模块也是值得的,因为该服务可以部署在具有大量CPU的主机上。通过将具有特定资源需求的模块转换为服务,您可以使应用程序更容易扩展。

当找出要抽取的模块时,查找现有的粗粒度边界(a.k.a接缝)是有用的。它们使模块变成服务变得更容易和便宜。这种边界的一个例子是仅通过异步消息与应用程序的其余部分进行通信的模块。将该模块变成微服务器可以相对便宜和容易。

如何抽取模块

抽取模块的第一步是在模块和单体应用之间定义一个粗粒度的接口。它大多是双向API,因为单体应用将需要服务拥有的数据,反之亦然。由于模块和应用程序的其余部分之间存在纠缠的依赖关系和细粒度的交互模式,因此实现这样一个API通常是一个挑战。由于域模型类之间的众多关联,使用域模型模式实现的业务逻辑尤其具有挑战性。您将经常需要进行重大的代码更改来破坏这些依赖关系。下图显示了重构。

一旦实现了粗粒度的界面,您就可以将模块变成一个独立的服务。要做到这一点,您必须编写代码,以使单体应用和服务通过使用进程间通信(IPC)机制的API进行通信。下图显示了重构之前,之中和之后的架构。

在这个例子中,模块Z是要抽取的候选模块。其组件由模块X使用,它使用模块Y.第一个重构步骤是定义一对粗粒度的API。第一个接口是由模块X用来调用模块Z的入站接口。第二个接口是模块Z用于调用模块Y的出站接口。

第二个重构步骤将模块转换为独立服务。入站和出站接口由使用IPC机制的代码实现。您将很可能需要通过将Module Z与Microservice Chassis框架相结合来构建服务,该框架处理诸如服务发现之类的交叉问题。

一旦您抽取了一个模块,您还可以独立于单体应用和任何其他服务开发,部署和扩展另一项服务。您甚至可以从头开始重写服务;在这种情况下,将服务与整体整合的API代码成为在两个域模型之间转换的反腐层。每次您抽取服务时,您将朝微服务方向迈出一步。随着时间的推移,单体应用将缩小,您将拥有越来越多的微服务器。

总结

将现有应用程序迁移到微服务器的过程是应用程序现代化的一种形式。 您不应该从头开始重写您的应用程序来转到微服务器。 相反,您应该将应用程序逐步重构为一组微服务器。 可以使用三种策略:实现新功能作为微服务; 从业务和数据访问组件拆分展现层组件; 并将单体应用中的现有模块转换为服务。 随着时间的推移,微服务器的数量将会增长,开发团队的灵活性和速度将会增加。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT技术精选文摘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据集成
数据集成(DataInLong)源于腾讯开源并孵化成功的 ASF 顶级项目 Apache InLong(应龙),依托 InLong 百万亿级别的数据接入和处理能力支持数据采集、汇聚、存储、分拣数据处理全流程,在跨云跨网环境下提供可靠、安全、敏捷的全场景异构数据源集成能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档