资讯详情

资讯详情

单体架构到微服务架构的渐进式迁移实战指南(advanced-java 微服务迁移综述)

单体架构到微服务架构的渐进式迁移实战指南advanced-java 微服务迁移综述【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/doocs/advanced-java导读单体应用规模膨胀后变更周期捆绑、扩展困难、可靠性下降等问题会集中爆发但“推倒重写”往往带来更大的风险。本文以 advanced-java 项目中的《迁移到微服务综述》为核心系统讲解 Martin Fowler 提出的绞杀者Strangler模式及其三种渐进式迁移策略停止挖掘、前后端分离、抽出服务并结合仓库中其他微服务文档补充请求路由器、胶水代码容灾层、粗粒度接口与 IPC 通信等落地细节。读完本文你将掌握一套不中断业务、可持续演进的单体应用微服务化路线图。为什么不要“大爆炸”式重写迁移单体应用到微服务架构本质上是一系列现代化改造过程。面对庞大臃肿的单体系统最直觉的想法是推倒重来Big Bang——用一套全新的微服务应用替换旧系统。但重写代码听起来诱人实际上充满风险且极易失败正如 Martin Fowler 所言“the only thing a Big Bang rewrite guarantees is a Big Bang!”大爆炸式重写唯一能保证的就是一场大爆炸重写失败的根本原因在于旧单体承载了大量未被文档化的业务规则、隐式依赖和边界情况全新重写很难完整复刻这些行为同时团队还要在迁移期间维持旧系统持续对外提供服务。因此更稳妥的路线是逐步迁移逐步生成新的微服务与旧的单体应用集成共处随着时间推移单体应用在整个架构中的占比逐渐下降直到完全消失或退化成为微服务架构中的一员。这一过程好比在高速公路上以限速 70 迈对行驶中的车辆做维护——虽有挑战但风险远小于停车重装。策略一停止挖掘Law of Holes——从新功能开始“Law of Holes”的谚语是当自己掉进坑里时第一件事就是停止继续挖掘。对于已经不可管理的单体应用这是最佳建议——停止让单体应用继续变大。请求路由器与胶水代码当开发新功能时不再为旧单体应用添加新代码而是将新功能直接开发成独立微服务。此时架构由四部分组成传统单体应用继续承载存量业务新服务以轻量级微服务方式承载新功能请求路由器Request Router处理入口 HTTP 请求类似 API 网关将新功能请求路由到新开发的服务将传统请求仍转发给单体应用胶水代码Glue Code将微服务与单体应用集成起来负责数据整合。微服务很少能真正独立存在它们经常需要访问单体应用的数据。胶水代码可能位于单体应用侧、微服务侧或两侧兼有它承担数据整合职责。微服务通过胶水代码从单体应用中读写数据通常有三种访问方式调用单体应用提供的远程 API直接访问单体应用的数据库自己维护一份从单体应用中同步的数据副本。胶水代码 容灾层Anti-Corruption Layer胶水代码也被称为容灾层anti-corruption layer因为它保护微服务全新的领域模型免受传统单体应用领域模型的“污染”在两种模型之间提供翻译功能。“Anti-Corruption Layer”这一术语首次出现在 Eric Evans 所著《领域驱动设计》Domain Driven Design中随后被提炼为一篇专门的白皮书。开发容灾层看起来优先级不高但它是避免陷入单体泥潭的必要组成部分。策略一的价值与局限将新功能以微服务方式实现有如下优点阻止单体应用继续膨胀避免其变得更加不可管理新微服务可以独立开发、独立部署、独立扩展开发者能提前感受微服务架构带来的不同开发体验。但该策略不解决单体应用本身的任何既有问题——要解决这些问题必须深入单体应用内部做出改变这正是策略二和策略三要处理的事。策略二将前端表现层与后端分离减小单体应用复杂度的另一个策略是将表现层与业务逻辑层、数据访问层分离。典型的企业应用至少由三个元素构成表现层处理 HTTP 请求响应 REST API 请求或提供基于 HTML 的图形接口对于复杂用户接口应用表现层往往是代码量最大的部分业务逻辑层完成业务逻辑的应用核心数据访问层访问数据库、消息代理等基础元素。在表现层与业务/数据访问层之间存在清晰的隔离。业务层通过一个由若干方面组成的粗粒度coarse-grainedAPI对外暴露内部包含业务逻辑元素。这个 API 是天然的拆分边界——将单体业务分割成两个更小的应用一个只含表现层另一个含业务逻辑与数据访问逻辑。分割后表现层应用通过远程调用与业务逻辑应用通信。分割的两个好处两部分可独立开发、部署和扩展特别地允许表现层开发者快速迭代用户界面进行 A/B 测试暴露的远程 API 可以被其他微服务调用为后续进一步服务化打下基础。策略二的局限该策略只是部分解决方案拆分后很可能两部分之一甚至全部仍然不可管理因此还需要第三种策略来消除剩余的单体架构。策略三抽出服务Extract Services第三种迁移策略是从单体应用中抽取某些模块使其成为独立微服务。每抽取一个模块单体应用就简单一分一旦转换足够多的模块单体应用本身就不再构成问题——要么彻底消失要么简单到退化为一个普通服务。如何排序先抽哪个模块一个巨大的复杂单体应用由成十上百个模块构成每个模块都是潜在的被抽取对象。决定先抽哪个模块通常是最大挑战一般遵循以下排序原则从最容易抽取的模块开始这能让开发团队积累足够的迁移经验为后续模块化工作带来巨大好处按获益程度排序从经常变化的模块开始转换模块为微服务通常很耗费时间将频繁变更的模块独立出来可以加速开发进程获益最大优先抽取资源消耗大户例如将内存数据库抽取为微服务并部署在大内存主机上将计算密集型算法应用抽取出来部署在 CPU 资源充足的主机上。通过这种方式应用可以按需扩展查找现有粗粒度边界例如只与其他应用异步同步消息的模块就是一个明显的边界可以简单容易地转换为微服务使移植工作更轻松。如何抽取模块两步走第一步定义粗粒度接口。抽取模块前必须先定义好模块与单体应用之间的粗粒度接口。由于单体应用需要微服务的数据反之亦然因此这更像一个双向 API。开发这种 API 很有挑战性——需要在负责依赖关系和细粒度接口模式之间做好平衡尤其对于使用领域模型模式的业务逻辑层来说难度更高经常需要改动代码来解决依赖性问题。第二步转换为独立微服务。完成粗粒度接口后编写代码使单体应用与微服务之间通过进程间通信IPC机制的 API 交换信息从而将模块转换为独立服务。以图中示例来说明假设正在使用 Y 模块的 Z 模块是备选抽取对象而 Z 模块的元素正被 X 模块使用。迁移第一步是定义两套粗粒度 API内部接口被 X 模块使用的接口用于激活 Z 模块外部接口被 Z 模块使用的外部接口用于激活 Y 模块。迁移第二步是将模块转换成独立服务内部和外部接口都改用基于 IPC 机制的代码通常还会将 Z 模块整合进一个微服务基础框架以便处理割接过程中的问题例如服务发现。抽取完成后该服务即可独立于单体应用和其他服务进行开发、部署和扩展。服务可以从头编写实现此时用于整合服务与单体应用的 API 代码即构成容灾层在两种领域模型之间做翻译。每抽取一个服务就向微服务方向前进一步随着时间推移单体应用越来越简单团队就能继续增加更多独立的微服务。迁移过程中的关键落地配套以下内容与策略一至三强相关是单体微服务化过程中必须配套解决的基础设施问题详见仓库中相关文档。服务通信同步与异步抽取出的微服务之间需要通过 IPC 通信。常用的方式包括REST/HTTP同步基于 HTTP/HTTPS 协议每个 URI 代表一种资源用 GET/POST/PUT/DELETE 操作资源请求之间无状态是最常用的服务间通信方式RPC同步远程过程调用客户端调用远端服务就像调用本地函数可基于 TCP/UDP 等传输协议消息中间件异步如 Kafka、RabbitMQ、RocketMQ、ActiveMQ通过轻量级消息总线解耦服务。服务注册与发现微服务之间需要互相定位可采用Eureka或Zookeeper集中管理服务。值得注意的区别是Zookeeper 保证 CP一致性 分区容错Eureka 保证 AP可用性 分区容错二者在 CAP 之间做了不同取舍。容错与降级防止雪崩微服务架构中一个请求往往涉及多个服务调用若某个服务不可用且没有容错措施极易引发一连串服务不可用即雪崩效应。可引入 Hystrix、Sentinel 等服务熔断与流量控制组件。数据一致性分布式事务的替代方案单体应用依赖单库 ACID 事务而微服务各服务持有私有数据跨服务事务无法依赖 2PC 时可转向事件驱动架构微服务在业务实体变化时发布事件订阅方消费事件更新自身实体从而实现最终一致性。事件驱动架构可配合本地消息表、数据库事务日志挖掘、事件源Event Sourcing等方式解决更新数据库与发布事件的原子性问题。这与策略一中微服务通过胶水代码从单体读写数据的诉求一脉相承——迁移期间新旧系统数据如何保持一致是必须提前设计的。部署与治理微服务数量增长后部署复杂度显著上升可参考单主机多实例、单虚拟机单实例、单容器单实例、Serverless等部署模式同时配套负载均衡Nginx/Ribbon、配置管理Nacos/Spring Cloud Config/Apollo、链路追踪Zipkin/Brave等治理手段保证迁移后的系统可观测、可运维。总结将现有单体应用迁移为微服务架构的现代化应用不应该通过从头重写代码来实现而应通过逐步迁移的方式推进。本文介绍的三种策略构成了完整的渐进式迁移路径停止挖掘新功能以独立微服务实现配合请求路由器和胶水代码容灾层防止单体继续膨胀前后端分离将表现层与业务/数据访问层拆开降低单体复杂度并暴露可复用的远程 API抽出服务按易抽取、高收益、资源敏感、边界清晰排序逐步将存量模块服务化。随着时间推移微服务数量不断增加单体应用逐步萎缩乃至消失开发团队的弹性与交付效率将获得显著提升。这一策略源自 Martin Fowler 提出的**绞杀者应用Strangler Application**模式——如同雨林中的绞杀藤缠绕大树生长最终留下树形的藤蔓结构。迁移过程务必保持业务连续性并同步建设服务发现、容错降级、事件驱动数据一致性、自动化部署等微服务治理配套才能让这条渐进式迁移之路走得稳、走得远。【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/doocs/advanced-java创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →