7

从单体迁移到微服务的十二种方法

 1 year ago
source link: https://www.jdon.com/61531
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从单体迁移到微服务的十二种方法
你的团队决定是时候摆脱那个旧的、笨重的单体了,它运行得很好,但是单体已经变得如此之大,以至于你花费更多的精力来维护它而不是添加功能。这里有 12 个技巧,可帮助您尽可能顺利地过渡到微服务

#1 确保你知道你在做什么
重写从来都不是一件容易的事,但是从单体应用到微服务,你改变的不仅仅是编码方式;你正在改变公司的运营模式。你不仅需要学习一个新的、更复杂的技术栈,管理层还需要调整工作文化,将人员重组为更小的跨职能团队
如何最好地重组团队和公司是值得单独发帖的主题。在本文中,我想重点介绍迁移的技术方面。
首先,在开始之前尽可能多地研究采用微服务所涉及的权衡是很重要的。您希望绝对确定微服务(而不是其他替代解决方案,例如模块化单体)是适合您的解决方案。
首先学习有关微服务架构的所有知识,并查看一些示例项目以了解其工作原理。这里有些例子

#2 制定计划
拆除单体应用需要大量准备工作,因为旧系统必须在过渡期间保持运行。
迁移步骤可以通过工单进行跟踪,并像任何其他任务一样在每个 sprint 中进行。这不仅有助于获得动力(实际上有朝一日实现迁移),而且让业务所有者了解团队如何计划实施如此大的变化。
在计划期间,您必须:

  • 解开单体内部的依赖关系。
  • 确定所需的微服务。
  • 为微服务设计数据模型。
  • 开发一种在单体和微服务数据库之间迁移和同步数据的方法。
  • 设计 API 并计划向后兼容。
  • 捕获单体应用的基线性能。
  • 为新系统的可用性和性能设定目标。

除非您从一个相当简单的单体架构迁移,否则您将需要高级技术,例如领域驱动设计 (DDD)。

#3 把所有东西都放在一个 monorepo 中
当你分解单体时,大量代码将从单体中移出并转移到新的微服务中。monorepo帮助您跟踪这些类型的更改。此外,将所有东西放在一个地方可以帮助您更快地从故障中恢复。
您的单体应用很可能已经包含在一个存储库中。因此,只需为微服务创建新文件夹即可。

v2-9a490ca1162a38a1ac27507df43cd64e_1440w.jpg

#4 使用共享 CI 管道
在开发过程中,您不仅会不断推出新的微服务,还会重新部署单体应用。这个过程越快、越轻松,你的进步就越快。设置持续集成和交付(CI/CD) 以自动测试和部署代码。
如果您使用 monorepo 进行开发,则必须牢记以下几点:

配置测试报告以快速发现和排除故障。

#5 确保你有足够的测试
当我们确定代码没有回归时,重构会更加令人满意和有效。自动化测试让您有信心持续发布单体更新。
一个很好的起点是测试金字塔。您将需要大量的单元测试、一些集成测试和一些验收测试

v2-6c5b6a67a977c1425e4c5b8a9bb6ffeb_1440w.jpg

旨在像在持续集成管道中一样经常在本地开发机器上运行测试。

#6 安装 API 网关或 HTTP 反向代理
随着微服务的部署,您必须隔离传入流量。迁移的功能由新服务提供,而尚未准备好的功能由单体提供。
有几种路由请求的方法,具体取决于它们的性质:

  • API 网关允许您根据经过身份验证的用户、cookie、功能标志或 URI 模式等条件转发 API 调用。
  • HTTP 反向代理的作用相同,但针对的是 HTTP 请求。在大多数情况下,单体实现了 UI,因此大多数流量都会流向那里,至少一开始是这样。
v2-975c170d473a3f3a30199362dd738397_1440w.jpg

使用 API 网关和 HTTP 反向代理将请求路由到适当的端点。您可以在非常细粒度的级别上在单体和微服务之间切换。
迁移完成后,网关和代理将保留——它们是任何微服务应用程序的标准组件,因为它们提供转发和负载平衡。如果服务出现故障,它们还可以充当断路器。

#7 考虑一体成型的模式
好的,这仅适用于您计划将容器或 Kubernetes 用于微服务的情况。在这种情况下,容器化可以帮助您实现基础架构的同质化。一体式整体模式包括在 Docker 等容器内运行整体。
如果您以前从未使用过容器,那么这是熟悉该技术的好机会。这样一来,您就离了解 Kubernetes 更近了一步。要学习的东西很多,所以要为陡峭的学习曲线做好计划:

  • 了解 Docker 和容器。
  • 在容器中运行你的单体应用。
  • 在容器中开发和运行您的微服务。
  • 完成迁移并掌握容器后,了解 Kubernetes。
  • 随着工作的进展,您可以扩展微服务并逐渐将流量转移到它们。
v2-84f6367f596bc92c593aba518599927e_1440w.jpg

容器化单体应用是标准化部署的一种方式,也是学习 Kubernetes 的绝佳第一步。

#8 热身于变化
习惯微服务需要时间,所以最好从小处着手,为新范式做好准备。留出足够的时间让每个人都进入正确的心态、提高技能并从错误中吸取教训,而不会受到最后期限的压力。
在这些初步的初步步骤中,您将学到很多关于分布式计算的知识。您必须处理云 SLA,为您自己的服务设置 SLA,实施监控和警报,定义跨团队通信的渠道,并决定部署策略。
选择一些容易开始的东西,比如与单体架构的其余部分几乎没有重叠的边缘服务。例如,您可以先构建身份验证微服务并路由登录请求。

选择一些容易开始的东西,比如简单的边缘服务。

#9 使用功能标志

功能标志是一种无需重新部署即可更改系统功能的软件技术。您可以使用功能标志在迁移时打开和关闭部分单体应用、试验替代配置或运行 A/B 测试。
启用功能标志的迁移的典型工作流程是:

  • 确定要迁移到微服务的单体功能的一部分。
  • 用功能标志包装功能。重新部署单体。
  • 构建和部署微服务。
  • 测试微服务。
  • 一旦满意,通过关闭该功能来禁用单体应用上的该功能。
  • 重复直到迁移完成。

因为功能标志允许我们将非活动代码部署到生产环境并随时切换它,所以我们可以将功能发布与实际部署分离。这为开发人员提供了极大的灵活性和控制力。

#10 模块化单体
如果你的单体应用是一堆代码,那么一旦迁移完成,你很可能会得到一堆分布式代码。就像在全面翻新之前收拾房子一样,模块化整体结构是必要的准备步骤。
模块化单体是一种软件开发模式,由独立且可互换的垂直堆叠模块组成。与模块化单体相反的是经典的 N 层或分层单体。

v2-0b86ac409f4839801589e0a68d5c1afc_1440w.jpg

分层的单体很难解开——代码往往有太多的依赖关系(有时是循环的),使得更改难以实现。
模块化单体是微服务的下一个最佳选择,也是迈向微服务的垫脚石。规则是模块只能通过公共 API 进行通信,默认情况下一切都是私有的。因此,代码的交织更少,关系易于识别,依赖关系清晰。

v2-a522fd779b1c86fd8e3527d12d977783_1440w.jpg

有两种模式可以帮助你重构单体:Strangler Fig 和 Anticorruption Layer。

Strangler Fig
Strangler Fig模式中,我们将整体重构从边缘到中心。我们在边缘咀嚼,逐步重写孤立的功能,直到整体重做。
模块之间的调用通过“扼杀外观”进行路由,该外观模拟和解释遗留代码的输入和输出。一点一点地,模块被创建并慢慢取代旧的单体。​

v2-14de71ebdfa4fe565e7dcdb9d08cdce1_1440w.jpg

单体是一次模块化的。最终,旧的巨石消失了,取而代之的是新的。

反腐败层模式
您会发现,在某些情况下,当您重构整体时,一个模块中的更改会传播到其他模块。为了解决这个问题,您可以在快速变化的模块之间创建一个转换层。此防腐败层可防止一个模块中的更改影响其余模块。

v2-62b8a9bc2956915fa055ea9f8aa224c4_1440w.jpg

反腐败层通过转换模块和单体之间的调用来防止更改传播。​

#11 解耦数据
超级强大的微服务使您能够随时部署任何微服务,而与其他微服务几乎没有协调。这就是为什么必须不惜一切代价避免数据耦合的原因,因为它会在服务之间产生依赖关系。每个微服务都必须有一个私有且独立的数据库。
意识到您必须将单体应用的共享数据库非规范化为(通常是冗余的)较小的数据库,这可能会令人震惊。但数据局部性最终将让微服务自主工作。

v2-93a98e0e79527dbff70628a7eba7fdef_1440w.jpg

上图是将数据解耦到独立的数据库中。
解耦后,您必须安装机制以在转换过程中保持新旧数据同步。例如,您可以设置数据镜像服务或更改代码,以便将事务写入两组数据库。

v2-f9c4f47dcaf0cb09da22e2ffbebef29c_1440w.jpg

在开发过程中使用数据复制来保持表同步。

#12 添加可观察性
新系统必须比旧系统更快、性能更高、可扩展性更强。否则,为什么要用微服务呢?
您需要一个基线来比较旧的和新的。在开始迁移之前,请确保您有良好的指标和日志可用。安装一些集中式日志记录和监控服务可能是一个好主意,因为它是任何微服务应用程序可观察性的关键组件。

v2-5c59efc8e2619d2f72bd88b1cace0282_1440w.jpg

结论
微服务之旅绝非易事。但我希望通过这些提示,您可以节省一些时间和挫败感。
请记住以小增量进行迭代,利用 CI/CD 来保证单体应用程序正在接受回归测试,并将所有内容保存在一个存储库中,以便在出现问题时随时回退。


banq​注:该文以小增量小心翼翼谨慎的方式重构原来系统,但是没有充分认识到单体与微服务是两种完全不同风格的架构,是南辕北辙的战略方向性区别,​为什么?因为微服务比单体​切分更小,如何小?是依据DDD有界上下文去切分的,而上下文需要从战略大背景大景观图下考虑的,所以,是团队认知上对业务理解巨大升迁,变革,这种忽然开朗的结果往往是方向上南北大区别,而摸着石头过河的小增量重构只适合方向未定或方向大概没有偏向情况下​。这种重构是听上去很有道理,但是完全不实用,从单体到微服务的迁移,不只是技术上的变化,还有业务知识的进步,更可能是团队彻底改变​。​新团队能忍受在旧思维旧单体下委曲求全吗?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK