将单体应用程序迁移到微服务

多年来,我处理过多个单体应用,并将其中一些迁移到了微服务架构。我打算写下我所学到的东西以及我从经验中用到的策略,以实现成功的迁移。在这篇文章中,我将以AWS为例,但基本原则保持不变,可用于任何类型的基础设施。

单体架构

单体架构是一个大型代码存储库,所有功能都在一个地方实现。随着应用程序功能和复杂性的增加,这使得它变得复杂且难以维护。代码存储库不仅包含支持相关功能的所有核心逻辑,还包含支持不相关功能的代码。即使是一个小错误修复或功能发布也需要测试才能完成应用程序。我遇到的主要痛点是:

  1. 协作:有“n”个工程师在一个存储库上工作。因此,合并冲突的可能性很大,这会导致解决冲突而不是专注于核心开发带来不必要的负担,从而减慢了功能发布的速度。

  2. Bug:随着时间的推移,关注点分离、代码质量和最佳实践都会逐渐消失。因此,很可能会引入不相关功能的错误。通常,我们对核心功能进行健全性测试,但会错过这些错误,或者发现自己惊讶地发现与遥远无关的更改的错误。

  3. 生产时间:在单体系统中,由于各种因素,创新的步伐受到阻碍。即使有完整的CI/CD系统和所有测试,由于仓库和测试的规模,开发测试、集成测试等需要时间,发布到生产也需要时间。

  4. 技术栈:单体系统在单一技术栈中实现,这限制了适应新兴技术的灵活性。此外,这也引入了学习曲线。

  5. 故障隔离:单体系统将所有组件捆绑在一起,一个模块/组件的故障可能会导致整个系统故障。

  6. 修复时间:有时,识别错误并修复它并不容易。由于不同的组件捆绑在一起,一个模块的更改可能会导致另一个模块出现问题。这会增加调试、修复并将补丁应用到生产的时间。

  7. 可扩展性:在单体系统中,扩展就时间和成本而言并不总是容易的。由于单体包含了所有组件,有很高的几率某些组件/代码块被大量使用,而其他则较少。因此,如果某个组件需要水平扩展,整个系统都需要扩展。

除了上述问题之外,还有其他问题。话虽如此,单体架构并不总是一个糟糕的选择,并且有多种优点:

  1. 快速实施,快速失败:在快节奏的环境中,没有自由遵循所有最佳实践并等待实施适当的软件应用程序来测试其产品市场适应性,总是首选实施 MVP 并进行 UAT了解 PMF。

  2. 开发:由于单体系统的所有组件都在单个代码库中实现,因此没有服务间通信/协作的开销,并且实现速度更快。

  3. 运营开销:只有一个系统需要处理。可以轻松实现警报监控并确保应用程序健康运行。这也减少了维护各种服务的运营开销。

  4. 性能:将所有代码集中在一处,操作可以更快。同样,这也取决于整体的大小和组件。

这些优势是根据具体情况而定的,并且在很大程度上取决于单体应用所实现的功能的大小。

典型的单体流程

将单体应用程序迁移到微服务_第1张图片

这是单体应用程序的典型流程,其中:

  1. 托管应用程序的基础设施由负载均衡器支持

  2. DNS 映射将交互重定向到基础设施,然后调用业务逻辑

  3. 实现单个数据库来保存数据

  4. 为了优化,可以有一个缓存层

  5. 为了完成用户请求,各个下游系统之间可能存在交互,编排在基础设施层内进行管理

这简化了很多事情,例如:

  1. 路由:所有流量路由到在单个或多个基础设施上运行的单个代码

  2. 数据库:无需担心数据隔离、数据共享等问题,数据由单个应用程序访问。

  3. Authn 和 Authz:单点身份验证实现易于实现和管理。

微服务

近年来,微服务模式开始流行并证明了自己。实施、管理、贡献和扩展这些服务变得更加容易。微服务可以小到单个 API 到多个相互相关的功能 API。使用微服务有多种好处,例如:

  1. 易于开发:开发、部署、测试和管理微服务的速度更快。相关功能可以组合在一起并独立开发。

  2. 调试:更容易调试、修复和部署。

  3. 可扩展性:根据需要,可以在不影响其他微服务的情况下扩展不同的微服务。

  4. 技术堆栈:灵活选择不同的堆栈来实现不同的功能

还有其他好处。话虽如此,微服务不仅仅带来好处,但也存在陷阱,例如:

  1. 成本:每个服务都在独立的基础设施上运行,这可能会导致更高的成本

  2. 运营:与越来越多的微服务相关的运营开销将会越来越多

  3. 依赖性:一个微服务可能依赖于许多其他微服务,这可能会导致延迟、authn、authz、隔离挑战

  4. 数据一致性:每个微服务可以有自己的数据存储。数据同步在分布式系统中也有其自身的问题。

典型的微服务流程

将单体应用程序迁移到微服务_第2张图片

迁移策略

将单体系统迁移到微服务并不是一件容易且简单的任务。在继续之前,需要从代码、功能、依赖关系等方面全面了解单体系统。一旦记录:

  1. 确定可以组合在一起的常见功能部分。这将帮助您设计所需的各种微服务。一旦确定,您就可以独立设计单独的服务。

  2. 一旦确定了所需的各种微服务,您可能需要一个编排层。例如,早些时候,单个端点足以让网页与整体交互,但对于微服务,每个端点都将具有单独的端点。我更喜欢BFF(Backend For Frontend)编排层,它将编排从前端到不同微服务的调用。

  3. 身份验证和授权是应用程序的一个非常重要的方面。对于微服务,每个微服务都有责任进行身份验证和授权。确定保护每个微服务的身份验证机制。

  4. 数据存储是另一个需要适当研究的方面。建议隔离每个微服务中的相关数据,但在某些情况下可能无法完全隔离。在这种情况下,识别此类数据并制定适当的实施计划来缓解任何竞争条件、数据泄漏、数据共享等。

  5. 可能存在一些常见的功能,例如从数据库读取、写入数据库、从缓存读取等,这些功能可以抽象为公共库并在这些微服务中使用。

  6. 建立通用的编码实践。对于各种不同的服务,不同的服务中可能存在不同的编码约定或实践。建立一个共同点将使其成为各种微服务的标准。

  7. 发布计划是另一个重要方面。这包括部署策略、识别 UAT 客户、测试计划、回滚计划等。

  8. Canary服务对于您的迁移非常重要。这将提供您的微服务运行状况的清晰画面。

  9. 比较器服务是另一个重要的部分。设计一项服务,将您的流量路由到整体服务和微服务。该服务将比较整体式服务和微服务的结果以确保数据准确性,以避免任何过度暴露信息的安全事件。一旦您有足够的信心,就可以将路由从整体更改为微服务。

  10. 操作健康状况和回滚策略是其他需要考虑的问题。制定明确的事件操作手册和缓解计划。

  11. 为每个微服务实施扩展以避免任何停机。


作者:Pranav Kumar Chaudhary

更多技术干货请关注公号【云原生数据库

squids.cn,云数据库RDS,迁移工具DBMotion,云备份DBTwin等数据库生态工具。

irds.cn,多数据库管理平台(私有云)。

你可能感兴趣的:(技术专栏,微服务,java,大数据,系统架构)