50、将单体应用转换为微服务:策略与实践

将单体应用转换为微服务:策略与实践

1. 转换背景与挑战

在软件开发中,当决定采用“绞杀单体应用”策略,即通过添加新特性作为微服务来逐步替换单体应用的功能时,会面临诸多挑战。在向微服务架构过渡的过程中,需要确保原有单体系统持续运行,同时将部分功能迁移到微服务中,以提高单体应用的可维护性,并减小新变更的影响范围。

以下是一些可能使单体应用向微服务转换过程复杂化的情况:
- 库和框架版本问题 :单体应用可能使用旧版本的库和框架,升级到最新版本不仅不完全向后兼容,还需要更新大量代码,且多年来的推迟导致新旧版本差异大,升级成本高、风险大。
- 编程语言选择 :单体应用可能使用的编程语言已不适合当前组织的环境,而团队希望使用不同的编程语言、框架或更新但不兼容的版本来开发新应用,这使得新应用无法直接调用单体应用中的组件。
- 协议和技术差异 :团队渴望使用新的协议和技术带来的潜在好处,但客户端应用通常依赖旧协议和技术(如SOAP、EJB)调用单体应用的服务,或者通过添加模块依赖直接调用内部逻辑。
- 业务逻辑复杂 :大多数单体应用是包含多个领域业务逻辑的大型系统,难以确定从何处以及如何拆分,团队往往不知从何入手,且拆分过程需要大量时间、精力、分析和重构。

2. 转换策略

可以采用迭代的方式将单体应用转换为微服务,具体步骤如下:
1. 识别拆分点 :在单体应用中寻找可以将其拆分为组件的位置,这些组件可以被提取、重构或替换为围绕领域建模的更小组件。
2. 确定分区 :找到单体应用中可以用微服务替换的功能分区(功能集群),并根据对团队和组织的价值对这些分区进行优先级排序,逐步替换。
3. 选择切入点 :可以从容易提取的部分开始,这有助于团队学习微服务并获得一些成果,也可以优先处理高价值的项目或任务,即那些造成问题且替换为微服务后能带来显著收益的区域。

3. 寻找拆分点的技术

可以通过以下技术寻找从单体应用中提取功能的分区:
- 寻找“细微裂缝”(Hairline Cracks) :在单体应用中寻找那些容易被拆分并替换为微服务的区域,这些区域通常具有定义良好的接口,代码中与其他部分松散耦合。例如,在大型单体应用中,有以下三种常见情况可以找到明显的“裂缝”:
- 现有REST或异步服务 :这是最容易重构的情况。如果现有服务已经兼容或可以兼容微服务架构,可将每个REST或简单异步服务从应用包中分离出来,独立部署。新的微服务应遵循云DevOps原则,只执行一项业务功能。
- 现有旧的分布式服务(如CORBA、SOAP或EJB) :这些服务通常基于功能设计,可以重构为基于资产的服务设计。对于简单的CRUD操作,可将EJB会话Bean接口或SOAP接口重新实现为RESTful接口;对于复杂操作,可以采用不同的方法构建RESTful服务。
- 简单的Web接口 :许多程序是简单的Web表单应用,作为数据库表的前端。如果有领域层,可以提取并围绕其构建新的微服务;如果没有,可以先创建领域层,再将其表示为RESTful服务。

以下是寻找“细微裂缝”的示例:
| 示例类型 | 描述 |
| — | — |
| Mono2Micro | IBM Mono2Micro是一个用于识别Java代码中外部松散耦合、内部紧密耦合部分的工具。它可以找到合适的“细微裂缝”,将代码分区,并生成包装代码以将分区重构为微服务。 |
| 电商应用 | 在电商单体系统中,分析购物车和结账功能,将其重构为更好的设计,以便更容易维护并提取为微服务。 |

4. 提取组件

当在单体应用中识别出“细微裂缝”后,可以将相关功能提取为独立的分布式组件,并递归应用此过程,直到组件大小适合作为微服务。提取组件有两种方法:
- 自下而上 :从寻找“细微裂缝”时发现的容易提取的部分开始,将其功能从单体应用中提取到微服务。例如,单体应用中现有的REST或异步服务、旧的分布式服务等通常可以直接提取为独立部署的微服务。
- 自上而下 :对于内部紧密耦合、难以拆分为小部件的大型组件,可以先提取较大的功能块,即使其中包含一些纠缠的部分。这样可以先获得向微服务迁移的好处,并使后续将这些纠缠部分重构为更小的微服务更容易。

在提取组件时,对于需要访问提取功能的现有客户端,可以通过Facade(外观模式)进行路由。例如,将组件X从单体应用中提取为微服务X′后,原调用组件X的客户端可以通过Facade调用微服务X′。

以下是提取组件的mermaid流程图:

graph LR
    A[单体应用] --> B[识别Hairline Cracks]
    B --> C{组件类型}
    C -->|松散耦合| D[直接提取为微服务]
    C -->|有一定耦合| E[重构后提取为微服务]
    D --> F[微服务部署]
    E --> F
    G[现有客户端] --> H[Facade]
    H --> F

在将单体应用转换为微服务的过程中,虽然可以使单体应用在转换期间继续工作并提供价值,且转换后的部分更易于维护、更改和部署,但也面临时间和精力投入大、需要同时维护两个系统等挑战。可以使用单体到微服务代理确保旧代码对新代码的访问,采用回放测试验证迁移,并应用包装设计模式(如适配器、装饰器、外观模式和代理模式)保护新服务不与单体应用纠缠。

将单体应用转换为微服务:策略与实践

5. 重构与提取的挑战及应对

在将单体应用转换为微服务的过程中,重构和提取组件并非一帆风顺,会面临诸多挑战。

首先是时间和复杂性问题。寻找“细微裂缝”(Hairline Cracks)并将其重构为更好的设计是一项困难且耗时的工作。而且,与任何重构工作一样,在重构完成之前无法立即看到收益。这就需要产品所有者和技术团队进行提前规划并达成共识,以确保有足够的资源和时间投入到偿还技术债务中。

其次,当业务能力在代码中没有明确定义或识别时,寻找“细微裂缝”会变得更加困难。在这种情况下,可以从数据入手,逆向分析代码。具体步骤如下:
1. 分析数据库结构和存储过程 :了解数据库中的数据结构和存储过程,这可以帮助发现可能存在的领域概念。
2. 追踪代码中的数据结构 :从调用存储过程的代码开始,逆向追踪到代码中表示领域概念的数据结构,即使这些数据结构的命名和定义可能不太清晰。
3. 建模领域概念 :以这些追踪到的数据结构为基础,开始围绕领域进行建模,识别系统中的聚合和有界上下文。

6. 转换过程中的注意事项

在将单体应用转换为微服务的整个过程中,还需要注意以下几点:
- 保持系统运行 :确保在转换过程中,原有的单体系统能够继续正常工作,特别是要保证现有客户端的正常使用。因为有些客户端可能不受自己控制,如其他团队或第三方的客户端。
- 遵循设计原则 :在寻找“细微裂缝”和提取组件时,要应用经过验证的微服务设计建模技术,以确定最佳的设计和领域边界,构建适合领域的微服务。
- 使用代理和测试 :对于从单体应用中提取或替换的代码,可以使用单体到微服务代理,确保旧代码对新代码的访问正常。同时,采用回放测试来验证迁移过程的正确性。
- 应用包装设计模式 :运用适配器、装饰器、外观模式和代理模式等包装设计模式,保护新的微服务不与单体应用产生过多纠缠。

7. 总结与实践建议

将单体应用转换为微服务是一个复杂且长期的过程,但通过合理的策略和方法,可以逐步实现这一目标。以下是一些实践建议:
- 制定清晰的计划 :根据单体应用的特点和组织的需求,制定详细的转换计划,明确各个阶段的目标和任务。
- 优先处理关键功能 :从高价值、容易提取的功能入手,逐步推进转换过程,让团队尽快看到成果,增强信心。
- 团队协作与沟通 :由于转换过程涉及多个团队和不同的技术领域,加强团队之间的协作和沟通至关重要,确保各个环节的顺利进行。
- 持续学习与改进 :微服务架构是一个不断发展的领域,团队要持续学习新的技术和方法,不断改进转换过程和微服务的设计。

以下是将单体应用转换为微服务的整体流程mermaid流程图:

graph LR
    A[单体应用] --> B[识别Hairline Cracks]
    B --> C{组件情况}
    C -->|松散耦合| D[直接提取组件]
    C -->|有一定耦合| E[重构后提取组件]
    D --> F[构建微服务]
    E --> F
    F --> G[微服务部署]
    H[现有客户端] --> I[Facade]
    I --> G
    J[监控与优化] --> G

通过以上策略和实践,能够更有效地将单体应用转换为微服务,提高系统的可维护性和灵活性,为业务的发展提供更好的支持。

建议类型 具体内容
计划制定 制定详细转换计划,明确各阶段目标和任务
功能处理 优先处理高价值、易提取功能
团队协作 加强团队协作与沟通
持续学习 持续学习新技术和方法,改进转换过程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值