0107-将Monolith重构为微服务
重构到微服务的概述
将单一应用程序转换为微服务的过程是应用程序现代化的一种形式。这是开发人员几十年来一直在做的事情。因此,在将应用程序重构为微服务时,我们可以重用一些想法。
一个不使用的策略是重写“Big Bang”。那就是当你将所有的开发工作集中在从头开始构建一个新的基于微服务的应用程序时。虽然听起来很有吸引力,但它极具风险,并可能以失败告终。据报道,马丁福勒说,“宇宙大爆炸改写的唯一保证是宇宙大爆炸!”
而不是Big Bang重写,你应该逐步重构你的单片应用程序。您逐渐构建一个由微服务组成的新应用程序,并与您的整体应用程序一起运行。随着时间的推移,单片应用程序所实现的功能量会减少,直到它完全消失,或者它变成另一个微服务。这种策略类似于以70英里/小时的速度在高速公路上行驶时为您的汽车提供服务 - 具有挑战性,但比试图进行大爆炸重写风险要小得多。
Martin Fowler将此应用程序现代化策略称为Strangler应用程序。这个名字来自扼杀者藤(又名扼杀者无花果)在雨林中发现。为了达到森林树冠上方的阳光,一棵扼杀藤蔓在树周围生长。有时候,树死了,留下一棵树形的藤蔓。应用程序现代化遵循相同的模式。我们将构建一个由遗留应用程序周围的微服务组成的新应用程序,最终将会终止。
让我们看看这样做的不同策略。
策略1 - 停止挖掘
洞的法则说,每当你在洞里,你应该停止挖掘。当您的单一应用程序变得难以管理时,这是很好的建议。换句话说,你应该停止使巨石更大。这意味着,当你正在实现新的功能时,你不应该添加更多的代码到庞然大物。相反,这种策略的主要想法是将这些新代码放在独立的微服务中。下图显示了应用此方法后的系统体系结构。
除了新服务和传统巨石之外,还有其他两个组件。第一个是处理传入(HTTP)请求的请求路由器。它与前面文章中描述的API网关类似。路由器将对应于新功能的请求发送到新服务。它将传统请求路由到整体。
另一个组件是胶合代码,它将服务与整体结合在一起。一项服务很少孤立存在,并且通常需要访问该巨石所拥有的数据。胶合代码驻留在整体或服务中,或两者都负责数据集成。该服务使用胶水代码来读取和写入巨石所拥有的数据。
服务可以使用三种策略访问整体数据:
- 调用整体提供的远程API
- 直接访问整体数据库
- 维护自己的数据副本,这是与monolith的数据库同步的
胶水代码有时被称为反腐败层。这是因为粘合代码阻止了具有自己的原始域模型的服务被来自传统整体域模型的概念所污染。胶水代码在两种不同型号之间转换。术语反腐败层首先出现在埃里克埃文斯的必读书籍Domain Driven Design中,然后在白皮书中进行了完善。发展反腐败层面可能是一项不平凡的任务。但是,如果你想从单一的地狱中发展出来,创建一个很重要。
作为轻量级服务实现新功能有两个好处。它可以防止单块变得更加难以管理。该服务可以独立于整体开发,部署和扩展。您将体验到您创建的每个新服务的微服务体系结构的好处。
但是,这种方法并没有解决巨石问题。为了解决这些问题,你需要打破庞然大物。让我们看看这样做的策略。
策略2 - 拆分前端和后端
缩小整体应用程序的策略是将表示层从业务逻辑和数据访问层分离。典型的企业应用程序至少包含三种不同类型的组件:
- 表示层 - 处理HTTP请求并实现(REST)API或基于HTML的Web UI的组件。在具有复杂用户界面的应用程序中,表示层通常是大量代码。
- 业务逻辑层 - 作为应用程序核心并实现业务规则的组件。
- 数据访问层 - 访问基础结构组件(如数据库和消息代理)的组件。
通常,一方面的表示逻辑与另一方面的业务和数据访问逻辑之间存在干净的分离。业务层具有粗粒度API,由一个或多个外观组成,这些外观封装了业务逻辑组件。这个API是一个自然的接缝,您可以将整体分割成两个更小的应用程序。一个应用程序包含表示层。另一个应用程序包含业务和数据访问逻辑。分离之后,表示逻辑应用程序会对业务逻辑应用程序进行远程调用。下图显示了重构之前和之后的体系结构。
以这种方式分割单块有两个主要的好处。它使您能够相互独立地开发,部署和扩展两个应用程序。特别是,它允许表示层开发人员在用户界面上快速迭代,并轻松执行A / B测试。这种方法的另一个好处是它暴露了一个可以被你开发的微服务调用的远程API。
然而,这个策略只是一个部分的解决方案。一个或两个应用程序很可能是一个无法管理的庞然大物。您需要使用第三种策略来消除剩余的巨石或巨石。
策略3 - 提取服务
第三种重构策略是将整体中的现有模块变为独立的微服务。每次你提取一个模块并把它变成一个服务,这个庞然大物就会缩小。一旦你转换了足够的模块,巨石将不再是一个问题。要么它完全消失,要么它变得足够小,它只是另一种服务。
确定将哪些模块转换为服务的优先顺序
一个庞大而复杂的单片应用程序由数十或数百个模块组成,所有这些模块都是提取的候选对象。确定首先转换哪些模块往往是具有挑战性的。一个好的方法是从几个易于提取的模块开始。这将为您提供一般微服务和特别是提取过程的经验。之后,你应该提取那些会给你带来最大好处的模块。
将模块转换为服务通常非常耗时。您希望根据您将收到的好处对模块进行排名。提取频繁更改的模块通常是有益的。将模块转换为服务后,您可以独立于单块进行开发和部署,这将加速开发。
提取资源需求明显不同于其他巨石的模块也是有益的。例如,将具有内存数据库的模块转换为服务,然后将其部署在具有大量内存的主机上是非常有用的。类似地,提取实现计算上昂贵的算法的模块可能是值得的,因为可以将服务部署在具有许多CPU的主机上。通过将具有特定资源需求的模块转变为服务,您可以使您的应用程序更容易扩展。
在确定要提取哪些模块时,查找现有的粗粒度边界(aka接缝)是非常有用的。它们使模块变成服务更容易,更便宜。这种边界的一个例子是只通过异步消息与应用程序的其余部分进行通信的模块。将该模块转换为微服务可能相对便宜且容易。
如何提取模块
提取模块的第一步是定义模块和整体之间的粗粒度界面。它很可能是一个双向API,因为Monolith将需要服务拥有的数据,反之亦然。由于模块和应用程序的其他部分之间存在纠缠的依赖关系和细粒度的交互模式,实现这样的API通常是一个挑战。使用域模型模式实现的业务逻辑对重构尤其具有挑战性,因为域模型类之间有许多关联。您经常需要进行重大的代码更改才能打破这些依赖关系。下图显示了重构。
一旦实现了粗粒度接口,就可以将模块转变为独立服务。要做到这一点,您必须编写代码来使Monolith和服务通过使用进程间通信(IPC)机制的API进行通信。下图显示了重构之前,期间和之后的体系结构。
在这个例子中,模块Z是要提取的候选模块。它的组件由模块X使用,它使用模块Y.第一个重构步骤是定义一对粗粒度的API。第一个接口是模块X用来调用模块Z的入站接口。第二个接口是模块Z用来调用模块Y的出站接口。
第二个重构步骤将模块转变为独立服务。入站和出站接口由使用IPC机制的代码实现。您很可能需要将模块Z与微服务机箱框架相结合来构建服务,该框架处理诸如服务发现等交叉问题。
一旦你提取了一个模块,你就可以开发,部署和扩展另一个服务,独立于整体和其他任何服务。你甚至可以从零开始重写服务; 在这种情况下,将服务与整体结合在一起的API代码成为在两个域模型之间进行转换的反腐败层。每次提取服务时,您都会朝微服务的方向迈出一步。随着时间的推移,巨无霸将萎缩,你将有越来越多的微服务。
概要
将现有应用程序迁移到微服务的过程是应用程序现代化的一种形式。您不应该从头开始重新编写应用程序,而转向微服务。相反,您应该逐渐将应用程序重构为一组微服务。您可以使用三种策略:以微服务实现新功能; 将业务和数据访问组件中的表示组件分开; 并将单块中的现有模块转换为服务。随着时间的推移,微服务的数量将会增长,开发团队的敏捷性和速度将会增加。
原文地址:https://www.nginx.com/blog/refactoring-a-monolith-into-microservices/
0107-将Monolith重构为微服务的更多相关文章
- Chris Richardson微服务翻译:重构单体服务为微服务
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服务部署 ...
- 微服务与SOA
微服务跟SOA有什么区别呢,可以把微服务当做去除了ESB的SOA.ESB是SOA架构中的中心总线,拓扑结构应该是星形的,而微服务是去中心化的分布式软件架构. 一.巨石(monolith) web应用程 ...
- 同事跳槽阿里P7,甩我一份微服务架构设计模式文档,看完我也去
给所有微服务架构开发者的忠告,我想对你们说: 第一,要记住微服务不是解决所有问题的万能“银弹”. 第二,编写整洁的代码和使用自动化测试至关重要,因为这是现代软件开发的基础. 第三,关注微服务的本质,即 ...
- 微服务、SOA 和 API:是敌是友?
为一个正在不断发展的企业对比关键的集成与应用程序架构概念 对比微服务架构和面向服务的架构(SOA)是一个敏感的话题,常常引起激烈的争论.本文将介绍这些争论的起源,并分析如何以最佳方式解决它们.然后进一 ...
- 微服务架构-选择Spring Cloud,放弃Dubbo
Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多. 在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的.从 ...
- 放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结
http://developer.51cto.com/art/201710/554633.htm Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经 ...
- 微服务、SOA 和 API对比与分析
摘要: 对比微服务架构和面向服务的架构(SOA)是一个敏感的话题,常常引起激烈的争论.本文将介绍这些争论的起源,并分析如何以最佳方式解决它们.然后进一步查看这些概念如何与 API 管理概念结合使用,实 ...
- Spring Cloud 微服务的那点事
什么是微服务 微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”. 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调 ...
- Java高并发高性能分布式框架从无到有微服务架构设计
微服务架构模式(Microservice Architect Pattern).近两年在服务的疯狂增长与云计算技术的进步,让微服务架构受到重点关注 微服务架构是一种架构模式,它提倡将单一应用程序划分成 ...
随机推荐
- Redis之ziplist数据结构
0.前言 redis初始创建hash表,有序集合,链表时, 存储结构采用一种ziplist的存储结构, 这种结构内存排列更紧密, 能提高访存性能. 本文介绍ziplist数据结构 1.ziplist存 ...
- Atitit.收银系统模块架构attilax 总结
Atitit.收银系统模块架构attilax 总结 1. 常规收银系统模块结构1 1.1. 商品管理1 1.2. 会员系统1 1.3. 报表系统1 1.4. 会员卡系统1 1.5. 库存管理1 2. ...
- C++语言基础(17)-运算符重载
运算符重载的格式为: 返回值类型 operator 运算符名称 (形参表列){ //TODO: } 一.在类里面实例运行符重载 #include <iostream> using name ...
- codeblocks如何watch数组
codeblocks13.12+GDB 调试的时候,main传了一个int a[10]给quicksort 但是在quicksort内部,debugger把a看成一个pointer而不是array,所 ...
- iOSXib布局后代码修改约束的值
如何修改autolayout 约束的值? 目前我已知的方法有5种 1.修改frame(有时候可能会不起作用,但可以做动画) 2.修改约束的float值 3.使用VisualFormat 语言 4. ...
- SpringMVC学习(一)小demo
首先看一下整个demo的项目结构: 第一步是导入Spring MVC单独使用时的最少jar包: 第二步在项目的web.xml中配置Spring MVC提供的拦截请求的Servlet: 全类名是:org ...
- 2038: [2009国家集训队]小Z的袜子(hose) 分块
: [2009国家集训队]小Z的袜子(hose) Time Limit: Sec Memory Limit: MB Submit: Solved: [Submit][Status][Discuss] ...
- vCenter创建标准网络
vmware虚拟化,有2种网络类型,一种是标准网络,另外一种是分布式网络.这里重点介绍标准网络,标准网络可通过vCenter创建vSwitch标准虚拟交换机(vSS).vSS的承载体是物理 ...
- java开发目前技术选型
目前系统采用 1.后端 服务框架:Dubbo.zookeeper 缓存:Redis.ehcache 消息中间件:ActiveMQ,kafka 负载均衡:Nginx 分布式文件:FastDFS 数据库连 ...
- HTML 事件的例子:
HTML 事件的例子: 当用户点击鼠标时 当网页已加载时 当图像已加载时 当鼠标移动到元素上时 当输入字段被改变时 当提交 HTML 表单时 当用户触发按键时