ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Archi - 如何将单体应用改造为微服务?

2021-10-11 15:04:53  阅读:216  来源: 互联网

标签:提取 服务 应用 改造 单体 API 模块 Archi


总结

1.分布式组件的优先级

  • 1、服务发现、服务路由、服务容错:这是最基本的微服务基础设施。
  • 2、接口框架、API 网关:主要是为了提升开发效率,接口框架是提升内部服务的开发效率,API 网关是为了提升与外部服务对接的效率。
  • 3、自动化部署、自动化测试、配置中心:主要是为了提升测试和运维效率。
  • 4、服务监控、服务跟踪、服务安全:主要是为了进一步提升运维效率。

根据优先级分析来看3和4两种是随着微服务节点数量的增加而越来越重要,前期拆分的服务较少并且团队对于微服务架构也在逐渐掌握中,可以暂时采用人工的方式,虽然效率低了点,但是不会因为某个环节熟悉程度不够而导致整体崩盘的情况。

 

2.三个改造策略

策略1:新老分离

当你的单体应用已经变得无法管理的时候,就不要再继续扩大它的规模了。比如你想添加新功能,不要在单体应用中添加代码,而要将新的代码放在另一个单独的微服务中。下图展示了使用这种方法后的系统架构:

 

 

 

除了新服务和旧的单体应用,还有两个组件。一个是请求路由(request router),用来处理过来的(比如HTTP)请求,类似于API网关。这个路由发送与新功能相应的请求到新的服务上,将旧服务相关的请求路由到单体应用上。

另一个组件是胶水代码(glue code),用来将服务与单体应用集成起来。一个服务很少是隔离存在的,需要访问单体应用的数据。胶水代码就负责这些数据集成。微服务组件可以通过它来读写单体应用中的数据。

一个服务可以通过三种方式访问单体应用中的数据:

  • 通过调用单体应用提供的远程API
  • 直接访问单体的数据库
  • 保存一份数据的副本,和单体数据库保持同步

胶水代码有时被称为防腐层(anti-corruption layer),可以防止拥有自己原始领域模型的服务,被来自单体领域模型的概念所影响。

胶水代码可以在两个不同的模型间充当翻译官,防腐层这个词最初出现在Eric Evans写的《Domain DrivenDesign》一书中。开发一个防腐层不是一个小工程,但如果你想从单体地狱中走出来,这是很重要的。

用轻量级的服务实现一个新功能,有很多好处。首先,可以防止单体应用变得更难以管理;其次,这个应用可以被独立地开发,部署和扩展。

然而,这个方法并不能解决在旧有的单体部分遇到的问题,你还需要破坏原有的单体部分。

 

策略2:前后端分离

缩减单体应用的一个策略是将表现层从业务逻辑和数据访问层中分离出来,一个典型的企业应用至少包括三种组件:

  • 表现层:这层组件用来处理HTTP请求,实现(REST)API或者基于HTML的Web
  • UI。在一个有着复杂的用户接口的应用中,表现层通常有大量的代码;
  • 业务逻辑层:应用的核心代码,用来实现业务规则;
  • 数据访问层:访问数据库或信息中介的组件。

在表现逻辑与业务和数据访问逻辑之间通常有着明显的区分。业务层有一个粗粒度的API,包含一个或多个外立面组成,外立面封装了业务逻辑组件。这个API是自然的『缝合』,所以可以将单体分割为更小的应用,一个应用包含了表现层,另一个应用包含了业务和数据访问层。分隔后,表现逻辑层应用可以远程调用业务逻辑层应用,下图展示了改造前后的架构:

 

这样分隔单体应用有两个主要好处。首先你可以独立地开发,部署和扩展两个应用,比如对于表现层开发者来说,他们可以实现用户界面的快速迭代,A/B测试也很容易实现;其次,这样做会向外开放一个微服务也可以调用的远程API。

但是这个策略只是部分解决方案,很有可能会变成两个混乱的单体应用。需要用下面第三个策略去减少单体部分的比重。

 

策略3:提取服务

第三个策略的目的是将单体中的模块,转变为单独的微服务。每次提取一个模块,就改造为微服务,单体部分就缩减了。一旦你转化了足够的模块,最后不管单体部分是完全消失了,还是变小成了另一个微服务,都不是问题了。

优先改造哪个模块?

三种思路:

  • 可以从容易被提取的开始,积累微服务的经验,然后提取那些能给你带来最大好处的模块。
  • 提取那些频繁变化的模块很有用,一旦你将这个模块提取出来,就可以独立开发和部署它了,可以加速开发。
  • 提取那些资源需求和其它部分有很大不同的模块。比如将一个有内存数据库的模块转变为服务,就可以把它部署在内存很大的主机上;同样的,提取那些实现复杂算法的模块,就可以把它部署在CPU多的主机上。总之这样做有助于你扩展应用。

 

如何提取一个模块?

第一步是在模块和单体之间定义一个粗粒度的接口。由于单体和微服务的数据互相都有需求,所以它很像一个双向的API。但是在这个模块和应用的剩余部分之间,有着混乱的依赖关系和细粒度的交互模式,所以实现这个API还是很有挑战的。通过域模型实现的业务逻辑,改造起来尤其困难,因为各个域模型间的关系复杂。通常需要进行大量的代码修改,去打破这些依赖。

一旦你实现了细粒度的接口,就可以将模块改造为一个独立的服务。要写代码实现单体和微服务间的通信,通过使用了IPC机制的API。下图展现了一个架构在改造前,改造中和改造后的样子:

 

 

 

 

在这个例子中,模块Z是待提取的模块。模块X使用了Z的组件,Z又使用了模块Y。

改造的第一步是定义一对粗粒度的API,第一个接口是模块X调用模块Z的入站接口,第二个是模块Z调用模块Y的出站接口;
第二步是将这个模块改造为独立的服务。入站接口和出站接口都通过IPC机制的代码实现。可能你需要通过结合模块Z到微服务底盘框架(用来处理横切关注点,比如服务发现)上,来构建这个服务。

一旦你提取了这个模块,就可以独立地开发,部署和扩展它了。你甚至可以从头重写这个服务,将这个服务和单体结合起来的API代码就成了防腐层,相当于两个域模型之间的翻译官。每次提取一个服务,都是向着微服务又进了一步,单体的比重会逐步缩减。

 

 

参考文献

https://blog.csdn.net/rickiyeat/article/details/62043588

https://blog.csdn.net/zhenghhgz/article/details/89380714

标签:提取,服务,应用,改造,单体,API,模块,Archi
来源: https://www.cnblogs.com/frankcui/p/15393374.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有