当前位置: 首页 > 科技观察

如何快速从复杂的单体应用迁移到微服务?

时间:2023-03-16 11:57:45 科技观察

【.com原稿】想必你已经了解了微服务及其工作原理,现在是时候讨论如何向微服务转型的关键话题了。为什么转向微服务单体应用程序很大(就代码行而言)、复杂(就功能依赖性、数据等而言),服务于跨地域的数千名用户,并且需要多名开发人员和IT工程师。单体应用程序可能如下图所示:图1:单体应用程序的基本结构有时,即使具有所有这些特征,应用程序最初也可能运行平稳,并且可能不会遇到应用程序可伸缩性或性能方面的挑战。但是使用它会出现问题,而且问题会因应用程序而异。例如,对于云或Web应用程序,您可能会因为更多用户使用该服务而出现可扩展性问题,或者由于更长的构建时间和回归测试,定期发布新更新可能变得成本高昂且困难重重。如图2所示,单体应用程序的用户或开发人员可能会遇到右侧列出的一个或多个问题。图2:单体应用程序的潜在问题此时迁移到微服务听起来更像是救命稻草,而不是一时兴起。应用程序的迁移类似于图3:图3:从单体应用程序迁移到微服务那么这种变化是如何发生的呢?有两种可能的情况:创建一个全新的应用程序。转换或迁移现有的单一应用程序。后一种情况的可能性更大,但无论当前情况如何,都值得了解这两种情况的来龙去脉。使用微服务创建新应用程序我还没有看到很多从头开始构建基于微服务的应用程序的真实场景。通常,应用程序已经就位,而我所处理的大多数应用程序更多是从单体架构到微服务架构的过渡。在这种情况下,架构师和开发人员的意图是重用一些现有的实现。但是由于该技能在市场上非常普遍,并且已经发布了一些成功的实现,我们将会看到更多从头开始构建基于微服务的应用程序的示例,因此探索这种场景当然是必要的。假设您已经弄清了所有需求,就可以着手处理您将要构建的应用程序的架构设计了。在您开始使用时,有许多常见的最佳实践需要考虑,这些在以下部分中进行了介绍。组织准备情况您需要问自己的第一个问题是您的组织是否已准备好过渡到微服务。这意味着您组织的各个部分现在需要从以下方面对构建和发布软件进行不同的思考:团队结构。整体应用程序团队(如果有的话)需要分解成几个了解或接受过微服务最佳实践培训的小型高性能团队。如图3所示,新系统将由一组独立的服务组成,每个服务负责提供特定的服务。这是微服务模式的一大优势:减少通信开销,包括多个正在进行的会议。团队应该按照他们试图解决的业务问题或领域来组织。然后,通信将最终确定要遵循的一组标准/协议,以便这些微服务可以相互协作。每个团队都必须准备好独立于其他团队运作。他们应该是标准Scrum团队的规模,否则沟通又会成为问题。执行是关键,每个团队都应该能够满足不断变化的业务需求。工具和培训。一个关键要求是组织准备投资新工具和员工培训。在大多数情况下,需要淘汰现有的工具和流程并采用一套新的工具和流程。这需要大量资本投资,专门用于招聘新技能和对现有员工进行再培训。从长远来看,如果采用微服务的决定是正确的,组织将看到成本节约,从而收回投资。基于服务的方法不同于单体应用程序,对于微服务,您需要一种基于服务的自我维持方法。应用程序可以被认为是一组松散耦合的服务,它们相互通信以提供完整的应用程序功能。每个服务都应被视为具有自己生命周期的独立服务,由独立团队开发和维护。这些团队从多种技术中进行选择,包括最适合其服务需求的语言或数据库。例如,对于电子商务站点,团队编写了一个完全独立的服务,它使用内存数据库,例如购物车微服务,以及另一个使用关系数据库的服务,例如订购微服务。一个真实的应用程序可能使用微服务来实现身份验证、帐户、用户注册和通知等基本功能,并将业务逻辑封装在API网关中,该网关根据客户端和外部请求调用这些微服务。提醒一下:微服务可以是由一个开发人员实现的小型服务,也可以是需要多个开发人员实现的复杂服务。对于微服务,大小无关紧要;这完全取决于服务要提供的一种功能。此时必须考虑的其他方面是扩展、性能和安全性。扩展要求可能会有所不同,应根据每个微服务级别的需要提供。应在所有级别考虑安全性,包括静态数据、进程间通信和传输中的数据。进程间(服务到服务)通信必须考虑的关键方面是安全和通信协议。异步通信是最好的选择,因为它保证所有的请求都能正常运行,不会长时间消耗资源。使用RabbitMQ等消息总线可以促进这种通信。它很简单,可以扩展到每秒数十万条消息。为了防止消息传递系统在发生故障后成为单点故障,必须正确设计消息传递总线以实现高可用性。其他选项包括ActiveMQ,这是另一个轻量级消息传递平台。安全是这个阶段的关键。除了选择正确的通信协议外,还可以使用AppDynamics等行业标准工具来监视和测量进程间通信。任何异常情况都应自动报告给安全团队。拥有数以千计的微服务,处理所有事情确实变得很复杂。如何借助发现服务和API网关来解决此类问题将在后面解释。技术选择转向微服务的最大优势在于它为您提供了选择。每个团队可以独立选择最适合特定微服务的语言、技术、数据库等。采用整体方法,团队通常没有这种灵活性,因此请确保您不要忽视和错过这个机会。即使团队正在处理多个微服务,也要将每个微服务视为一个独立的服务并对其进行分析。在为每个微服务选择技术时,必须牢记可扩展性、部署、构建时间、集成和插件可操作性等。对于数据较少但访问速度较快的微服务,内存数据库可能是最合适的,而其他微服务可能使用相同的关系数据库或NoSQL数据库。履行履行是关键阶段,这是所有培训和最佳实践知识派上用场的地方。要记住的几个关键方面包括:独立性。每个微服务都应该是高度自治的,有自己的生命周期和相应的流程。它的开发和维护不依赖于其他微服务。源代码控制。必须部署适当的版本控制系统,并且每个微服务都遵循一个标准。统一代码库也很有帮助,因为它可以确保所有团队使用相同的源代码控制。它有助于从代码审查到在一个地方轻松访问所有代码的一切。从长远来看,有必要对所有服务进行相同的源代码控制。环境。所有不同的环境,如开发、测试、登台和生产阶段,都必须得到适当的保护和自动化。这里的自动化包括构建过程。这样,代码就可以根据需要集成,主要是每天集成。有几种工具可用,但Jenkins被广泛使用。Jenkins是一种开源工具,可帮助自动化软件构建和发布流程,包括持续集成和持续交付(CI/CD)。故障安全。软件故障是不可避免的。微服务开发必须解决下游服务的故障处理问题。其他服务的故障必须是不可见的,这样用户就看不到故障。这包括管理服务响应时间(超时)、处理下游服务的API更改以及限制自动重试次数。使用微服务时,不要害怕通过复制和粘贴来重用代码,但要在一定范围内这样做。这可能会导致代码重复,但这优于使用最终耦合服务的共享代码。在微服务中,你需要的是解耦,而不是紧耦合。比如,您将编写代码来使用服务的输出响应。每次从任何客户端调用相同的服务时,您都可以复制此代码。重用代码的另一种方法是创建公共库。多个客户端可以使用同一个库,但是每个客户端都应该负责维护它的库。如果你创建了太多的库,每个客户端维护一个不同的版本,有时会变得很困难。在您包含同一库的多个版本的情况下,由于向后兼容性和类似问题,构建过程可能会变得困难。只要你能在客户端控制库和版本的数量,并对它们执行严格的流程,它可以采用任何一种方式,这取决于你的需求。这绝对有助于避免大量代码重复。考虑到大量微服务,调试问题可能会变得很困难,因此您需要在此阶段进行某种检测。最佳实践之一是用唯一的请求ID标记每个请求,并记录每个请求。此唯一ID标识原始请求,并应由每个服务传递给任何下游请求。一旦发现问题,您可以通过日志清楚地回溯并确定有问题的服务。如果您构建集中式日志记录系统,此解决方案最有效。所有服务都应以标准化格式将所有消息记录到此共享系统,以便团队可以根据需要从一个地方(从基础设施到应用程序)重放事件。用于集中日志记录的共享库值得研究。有几种理想的日志管理和聚合工具,例如ELK(Elasticsearch、Logstas和Kibana)和Splunk。部署自动化是部署过程中的关键。没有它,微服务模式几乎不可能成功。由于可能有数百或数千个微服务,自动化对于敏捷交付至关重要。想象一下部署和维护数以千计的微服务。当其中一个微服务失败时会发生什么?你怎么知道哪台机器有足够的资源来运行你的微服务?如果没有适当的自动化,处理这种情况会变得非常复杂。可以使用Kubernetes和DockerSwarm等各种工具来自动化部署过程。操纵整个过程的操作部分也需要自动化。同样,我们谈论的是成百上千个微服务,组织能力需要足够成熟才能处理这种级别的复杂性。您需要一个包含以下内容的支持系统:从基础架构到应用程序API,再到首英里性能,一切都受到监控,并通过适当的阈值实施自动警报。考虑构建实时仪表板,在出现问题时弹出数据和警报。按需可扩展性。对于微服务,扩展是最简单的任务。配置要扩展的微服务的另一个实例,只需将其放在现有负载均衡器后面即可。但在规模上,这也需要自动化。只需设置一个整数值,告诉您要为特定微服务运行多少个实例。API是公开的。在大多数情况下,API应该对外公开以供外部用户使用。***为此任务使用边缘服务器,它处理所有外部请求。它可以使用API网关和发现服务来完成任务,您可以为每种设备类型(例如移动设备或浏览器)或用例使用一个边缘服务器。Zuul是Netflix开发的开源应用程序,可用于此功能和其他功能。断路器。向故障服务发送请求毫无意义。因此,可以构建断路器来跟踪对每个服务的每个请求的成功或失败。在多次失败的情况下,对特定服务的所有请求都应在指定的时间段内被阻止(即断开电路)。在指定的时间过去后,应进行另一次尝试,依此类推。一旦响应成功,重新连接电路。这应该在服务实例级别完成。Netflix的Hystrix提供了一个开源的断路器实现。将单体应用程序迁移到微服务虽然基于微服务构建新应用程序的大多数最佳实践也适用于从现有的单体应用程序迁移,但还有一些额外的指南可以使迁移更容易、更高效。虽然将整个单体应用程序转换为完全基于微服务的应用程序听起来不错,但将每个功能转换为微服务可能效率不高,在某些情况下可能成本很高。毕竟,您最终是从头开始编写应用程序。正确的迁移方式可能需要循序渐进,如图4所示:图4:基本迁移步骤,从单体应用到微服务下一个问题是:当前的单体应用从哪里开始?如果应用程序真的很旧并且分解它既费时又困难,那么从头开始可能会更好。在其他部分代码可以快速禁用且技术架构没有完全过时的情况下,最好先将组件重建为微服务并替换旧代码。微服务标准那么问题就变成了哪些组件应该首先迁移甚至根本不迁移。这让我想到了所谓的“微服务标准”,它概述了选择和优先考虑哪些功能应该迁移到微服务的可能方法之一。它们是您创建的一组规则,用于根据组织当时的要求确定将现有单体应用程序的组件转换为微服务是否合适。时机在这里很重要,因为组织的要求可能会不断变化,您可能不得不返回并将更多组件转换为微服务。换句话说,由于需求的变化,单体应用程序的附加组件可能有资格进行转换。以下是在转换过程中被认为是微服务标准的几个最佳实践:①您需要确定哪些功能被频繁使用,然后将经常使用的服务或应用程序功能首先转换为微服务。请记住:微服务仅执行一项定义明确的服务。牢记这一原则,相应地对您的应用程序进行分区。②可能有性能不佳的组件,其他替代品一应俱全可能有开源插件,或者您可能想从头开始构建服务。应该牢记的要点之一是微服务的边界。只要你设计你的微服务来做一件事,就没问题。建立界限通常很困难,但您可能会发现练习起来更容易。另一种看待微服务边界的方式是,整个微服务应该在几周内重写,而不是需要几个月才能重写的服务。③可以使用更好的技术替代方案或多语言编程领域特定语言来帮助解决问题领域(problemdomain)。对于您过去收到许多改进请求并希望将来继续这样做的组件尤其如此。如果您认为不仅可以使用新的语言或上市的功能简化此类组件的实现,而且将来的维护和更新会更容易,那么现在是应对这种变化的时候了。在其他情况下,您可能会发现另一种语言提供的并发抽象比您当前使用的语言更容易。一种新语言可以用于特定的微服务,而应用程序的其余部分仍然使用不同的语言。同样,您可能希望某些微服务非常快,并且可能决定用C语言而不是其他高级语言来编写它们以获得最大收益。归结为利用这种灵活性。④存储替代方案或多语言持久性大数据流行,如果使用NoSQL数据库代替关系数据库,应用程序的某些组件可能会提供价值。如果您的应用程序中的任何此类组件可以从这种替代方案中受益,那么可能是时候切换到NoSQL了。这些是您在单体应用程序中为每个服务或功能应该考虑的关键方面,您需要首先关注这几个项目的转换。一旦从高优先级部分获得值,就可以应用其他规则。⑤修改请求在任何软件生命周期中跟踪的一个重要方面是新的改进请求或更改。由于构建和部署时间而具有更多更改请求的功能可能适合微服务。分离这些服务可以减少构建和部署时间,因为您不必构建整个应用程序,只需更改微服务,这还可以缩短应用程序其余部分的可用性时间。⑥应用的某些部分总是增加部署的复杂性。在单体应用中,即使某个功能没有改变,你仍然要完成整个构建和部署过程。如果是这种情况,拆分这些组件并用微服务替换它们可能会有所帮助,这可以减少单体应用程序其余部分的总体部署时间。⑦辅助服务在大多数应用中,核心或主要服务都依赖于一些辅助服务。如果没有此类辅助功能,核心服务的可用性可能会受到影响。例如,在服务台应用程序中,工单依赖于产品目录服务。如果产品目录服务不可用,用户将无法提交工单。如果是这种情况,就应该将辅助服务转为微服务,保证高可用,更好地为核心服务服务。(这些也称为断路器服务。)根据应用程序,这些标准可能需要将大多数服务转换为微服务。创建路线图。重新构建服务一旦确定了要迁移到微服务的功能,就可以按照前面描述的最佳实践开始重新构建所选服务。以下是需要牢记的几个方面:微服务定义。为每个功能定义合适的微服务,包括通信机制(API)和技术定义等。考虑现有功能使用的数据,或为微服务创建和规划相应的数据策略。如果该功能位于像Oracle这样的密集型数据库上,那么迁移到MySQL是否有意义?确定您将如何管理数据关系。***,将每个微服务作为单独的应用程序运行。重建代码。如果你没有改变编程语言,你可以重用一些代码。考虑存储/数据库层:共享与专用、内存与外部。除非需要,否则目的不是添加新功能,而是重新打包现有代码并公开所需的API。在开始编码之前,确定您的源代码控制和版本控制机制,并确保您遵循这些标准。每个微服务都是一个单独的项目,部署为一个单独的应用程序。数据迁移。如果您决定创建新数据库,请同时迁移旧数据。这通常是通过编写简单的SQL脚本来完成的,具体取决于您的源代码和目标。单体代码。最初将现有代码保留在整体中,以防万一您需要回滚。您可以更新其余代码以使用新的微服务,或划分应用程序流量(如果可能)并同时使用单体和微服务版本。这使您有机会测试并专注于性能。一旦有信心,您就可以将所有流量迁移到微服务,禁用或删除遗留代码。独立构建、部署和管理。独立构建和部署每个微服务。当微服务推出新版本时,新旧版本之间的流量可以重新划分。这意味着您可能在生产环境中运行同一微服务的两个或多个版本。一些用户流量可以路由到新的微服务版本,确保服务正常运行。如果新版本不是在最新状态下运行,很容易将所有流量回滚到以前的版本并将新版本发送回开发团队。这里的关键是建立一个可重复的、自动化的部署流程,力求实现持续交付。删除旧代码。只有在确认一切都已正确迁移并按预期运行后,才能删除临时代码并将数据从旧存储位置移除。确保在此过程中进行备份。微服务的混合方法编写全新应用程序的开发人员可以直接按照微服务架构原则和蓝图构建应用程序软件。开发人员有时会采用微服务和单体应用程序的混合方法。在这种情况下,他们可以将应用程序的某些组件开发为微服务,其余组件则根据某些标准遵循标准SOA/MVC实践。这个想法是,并非应用程序的所有组件都可以转换为微服务。微服务提供了很大的灵活性,但这种灵活性是有代价的。混合方法旨在平衡灵活性和成本,并且稍后可以根据需要采用单体应用程序中的组件并将其转换为微服务。关键是在此过渡期间牢记方法和微服务标准。好处来了。您认为从单体架构迁移到微服务架构的关键点是什么?扫描下方二维码关注技术栈公众号。欢迎在技术栈微信上留言讨论公众号。小编将选出评论最精彩的5位网友,赠送一本书《Spring 5开发大全》~活动截止时间为1月11日中午12:00。特别感谢北京大学出版社为本次活动提供书籍赞助。迫不及待送书的朋友可以点击阅读原文直接购买。本书简介本书力求对Spring框架进行全面的介绍,涵盖Spring核心、测试、数据访问、Web开发、响应式编程、系统集成、微服务等共26章。百科全书”。同时,本书基于Spring5版本编写。除了Spring5版本的新特性外??,还介绍了REST服务、响应式Web开发、微服务设计、Spring等方面的前瞻技术。Boot,SpringCloud,每个知识点除了讲解Spring的理论知识外,还辅以大量的代码案例,理论联系实际,操作性更强,本书主要面向Java开发者,以及对以Spring为中心的JavaEE开发感兴趣的计算机科学专业的学生、软件开发人员、系统架构师。【原创稿件,合作站点转载请注明原作者和出处.com】