跳至主要内容

您在寻找什么?

探索我们的服务,了解我们如何帮助您实现目标

SaaS单体架构模块化改造:先重构,仅在测试验证后才拆分

按此顺序对SaaS单体架构进行现代化改造:围绕它添加测试和监控,将其拆分为带强制边界和独立数据的模块,并作为单一可部署应用运行。仅当某模块急需独立发布节奏、扩展能力或隔离时,才将其提取为独立服务。

预约解决方案评审 查看相关服务

作者 Netbase Commerce and Platform Engineering Desk · 审阅者 David (CEO) · 更新于 · 1 分钟阅读

star

本指南面向SaaS创始人、CTO及工程主管,适用于因每次变更都牵一发而动全身导致产品交付缓慢的团队。本指南假设产品已上线并有付费租户。首个版本的构建方法请参阅SaaS MVP架构路线图,更宏观的视角请参阅SaaS平台工程指南,重建、重构与重平台之间的通用选择请参阅数字化转型与现代化指南。

本指南内容

单体架构真的是问题所在吗?

单体架构是将一个应用作为一个单元部署。这本身并非缺陷:Martin Fowler的“单体优先”建议指出,几乎所有成功的微服务案例都始于一个规模过大的单体架构,而在充分了解业务领域之前,很难划定稳定的服务边界。在着手重构之前,请先寻找以下迹象:

  • 变更相互冲突。多个团队编辑同一文件,发布需要相互等待,一个小修复需要完整回归测试。
  • 一处故障波及全局。一个繁重的报告或导入任务会拖慢所有租户的登录和计费。
  • 没有人能解释某个部分。代码深入访问其他代码的数据,导致一处改动引发另一处故障。
  • 某个工作负载需要差异化处理。搜索、媒体处理或AI功能需要不同于其他部分的硬件、扩展方式或发布规则。

不要为其他问题而重构。页面缓慢通常是索引缺失所致,发布不稳定通常是测试缺失所致,账单过高通常是缺乏成本归因所致——后者请参阅我们的云成本控制指南。如果系统整体已老旧、不受支持或不透明,请先运行遗留系统评估检查清单。

目标:在拆分为服务之前先实现模块化单体架构

模块化单体架构仍是一个可部署的应用,但其代码被划分为多个模块,每个模块有清晰的公共接口和独立数据。Shopify工程团队描述了其大型Rails应用采用的这一方法:具有明确边界的组件,使开发者只需关注与自己相关的部分,测试也可针对单个组件而非整体运行。同一篇文章列举了团队在重新开始时会以不同方式处理的经验教训,因此请为迭代做好规划。

让模块成为真正的模块而非仅仅是文件夹,需具备:

  1. 公共接口。其他模块通过调用函数或发送事件进行交互,绝不直接访问内部实现。
  2. 数据所有权。每个模块拥有自己的数据表,其他模块不直接读取或联表查询。
  3. 负责团队。一个团队对模块的行为和测试负责。
  4. 强制规则。构建检查在模块导入另一模块内部实现时报错。

对于SaaS产品,典型的模块包括身份与访问、租户与权益、计费与订阅、核心产品领域、通知和报告。租户上下文贯穿所有模块;多租户架构指南解释了这一决策所依赖的隔离选项。

选择路径

路径优势风险适用场景
强化单体架构:添加测试、监控、查询和发布修复成本最低;通常能消除症状结构依然耦合混乱痛点是速度或稳定性,而非耦合问题
原地模块化单体架构,逐模块推进单一部署,单一数据库引擎,模块间无网络调用需要严格自律;没有检查机制时边界容易退化耦合拖慢团队但规模尚可管理
使用绞杀者模式提取部分服务隔离热点路径或受监管区域分布式故障、数据同步、更多运维工作某个经过验证的模块需要独立扩展、发布节奏或隔离
重写为微服务每个部分从零开始耗时最长,需重新学习旧规则,功能冻结几乎不适用;仅当旧代码完全无法演进时

大多数产品最终会形成一个模块化核心加零至少数个提取服务的结构。团队应将完整的微服务体系视为需要积累才能达到的目标,而非出发点。

寻找接缝,然后划定边界

接缝是代码中某一部分可以以较小代价与其他部分分离的位置。要从实证而非架构图来寻找接缝:

  • 依赖关系图。生成真实的导入关系图。入站调用多、出站调用少的模块是好的首选候选;耦合严重的核心部分留到最后处理。
  • 数据所有权。对每张数据表,列出哪些代码对其进行读写。被多处代码写入的数据表说明边界尚未划定。
  • 变更历史。经常一起变更的文件通常属于同一模块。独立变更的文件则暗示存在边界。
  • 业务语言。在不同地方含义不同的名称,例如计费和登录中的“账户”,标志着领域之间的边界。

选择第一个模块时,应优先考虑低风险、高学习价值的模块:功能清晰、接口小、共享数据少。通知或报告模块通常符合条件。计费和身份认证模块应等方法经过验证后再处理,且需格外谨慎,因为这两处的错误会影响所有租户。

分步骤:模块化路径

  1. 让单体架构安全可变更。

    添加监控、可重复的发布流程,以及记录系统当前行为(包括异常行为)的特征化测试。

  2. 梳理并命名模块。

    确认模块列表、各模块负责团队及预期依赖方向。

  3. 在构建中强制边界。

    添加在禁止导入时报错的规则。先以仅报告模式启动,逐模块收紧。

  4. 分离数据。

    通过调用所属模块的接口消除跨模块联表查询,然后将数据表或Schema移至该接口之后。每条记录保留租户标识符。

  5. 用接口和事件替换内部调用。

    缓慢或可选的工作,如发送邮件和使用量事件,移入单体架构内的异步事件。

  6. 仅在满足条件时才提取服务。

    候选模块必须有可量化的需求:独立扩展规格、独立发布节奏、安全或合规边界,或必须由某个团队端到端负责。

  7. 逐步迁移并保留回退路径。

    在前端添加路由层,将少量租户引流至新组件并对比结果。Microsoft的绞杀者无花果模式描述了这种渐进式替换方式,防腐层可防止新旧模型相互渗透。

每个步骤单独交付。如果项目在第4步后停止,产品仍然优于之前的状态。

迁移过程中的租户、计费与数据处理

多租户架构是重构中容易出现隐患的地方。以下三条规则有助于规避:

  • 租户上下文不可省略。每个模块和每项新服务都必须接收并强制执行租户标识符,最好通过共享代码实现,而非手动重复。
  • 分批迁移租户。从内部和友好租户开始,观察错误和性能,再逐步扩大范围。对十个小租户有效的迁移方案,未必适用于拥有多年数据的大租户。
  • 将计费和权益视为合同。代码底层变更期间,使用量事件和套餐限制对客户而言必须保持不变。在切换前,对比新旧路径的发票和权益结果。

数据迁移需要针对迁移过渡期间的读写制定方案:双写、变更捕获或短暂冻结,每种方案事后都需进行对账核查。

现代化改造中的AI

AI可以加速模块化过程中的阅读和文档梳理工作,而工程师保留所有决策权。适用场景包括:总结未记录模块的功能、根据依赖关系图提出候选边界,以及起草待审查的特征化测试。生成的代码和测试仅在经过人工审阅且测试套件通过后才合并。Netbase JSC与主流商业和开源AI模型合作,具体选型根据项目而定。以下各项说明其在 Netbase JSC 的成熟度。

已有交付记录与尚无记录的内容

Netbase JSC 构建并运营多租户SaaS产品,这也是本指南的写作背景:

  • Cloodo Workspace。一款将CRM、HRM、云ERP和AI模块整合于一体的工作管理数字工作空间,由 Netbase JSC 作为业务部门构建并运营(Cloodo记录)。
  • 某美国客户的云ERP(未具名)。一套多租户云ERP,Netbase JSC 自2020年起作为离岸开发及管理合作伙伴持续开发(云ERP记录)。
  • Printcart。Netbase JSC 业务部门旗下的Web to Print SaaS(Printcart记录)。
  • Netztech。一家商店在35个工作日内从Magento 1迁移至Magento 2 Commerce(Netztech记录)。这是平台迁移,而非单体架构拆解。

Netbase JSC 的交付生命周期包含模块化和产品化组件,其SaaS产品加速器由可复用模块构建而成。

尚无记录的内容。目前没有任何已发布的 Netbase JSC 记录描述将在线SaaS单体架构拆解为模块或服务的案例,也没有任何记录发布此类工作的持续时间、部署频率、成本或性能结果。上述方法来源于所引用文献和通用工程实践,而非 Netbase JSC 的实测成果。

备选方案:由谁主导工作

路径优势适用场景
自有团队对产品了解最深有足够人力且团队中有人做过模块化改造
同时负责后续运营的产品服务商快速启动并保持延续性希望由一方负责设计、变更和运营
架构评审,然后组建混合团队在承诺之前,独立审视接缝和优先级团队资源紧张,工作顺序尚不明确

四个标准决定选择:测试和监控是否存在、有多少人了解旧代码、迁移期间需要同步推进多少路线图工作,以及架构后续由谁负责。Netbase JSC 从对租户、计费、安全和成本的架构评审开始,然后规划分片。在 Netbase JSC 定制开发项目中,客户拥有为其创建的知识产权,大多数项目在探索阶段后以固定总价合同执行。相关服务详见SaaS开发和云平台工程。

本指南的局限性

  • 每个代码库各有不同;第一份依赖关系图往往会改变原有计划。
  • 不同框架和编程语言提供不同的边界强制工具;请检查所用技术栈的支持情况。
  • 来源仅引用其所记录的内容;未声明任何速度、成本或可靠性数据。

与 Netbase 顾问规划下一步

常见问题

通常不建议作为第一步。先在单一应用内将代码重构为模块,仅当某个模块有可量化的独立扩展、发布节奏或隔离需求时,才将其提取为服务。

取决于代码规模、测试覆盖率以及数据耦合程度。Netbase JSC 在完成架构评审和第一份依赖关系图后提供估算,不公布典型工期。

可以,前提是工作以分片方式交付,且构建在新边界出现时即强制执行。请为两者都规划好人力。

请先进行评估。如果平台不受支持或规则不明,重平台或探索阶段可能需要先于模块化进行。

下一步

告诉我们产品目前的部署方式、有多少团队在修改它,以及哪个部分最令人头疼,我们将安排解决方案评审,梳理接缝并提出第一个模块建议。您也可以阅读更多 Netbase JSC 洞察。

AI就绪SaaS开发——来自自营SaaS平台的团队 AI就绪SaaS开发——来自自营SaaS平台的团队

Netbase JSC为创始人和产品团队提供SaaS开发服务,助力多租户订阅软件的上线与规模化扩展,涵盖客户愿意付费的AI功能。我们自主构建并运营SaaS平台Printcart及AI驱动的Cloodo工作空间,并将这一经验带入客户项目。典型SaaS MVP周期为8至12周,具体取决于范围、集成及评审速度。

Learn More
line
面向SaaS与电商工作负载的AI就绪云平台工程 面向SaaS与电商工作负载的AI就绪云平台工程

Netbase为SaaS与电商团队提供云平台工程服务,在AWS、Google Cloud、DigitalOcean或Cloudflare上为软件及其AI功能构建安全、可重复的运行环境。我们设计架构、以代码定义环境、集成托管服务与AI服务,并交付一套您的团队可自主运营的平台——与我们自身运营方式一致。

Learn More
line
SaaS产品加速器:基于Netbase成熟模块,快速构建AI就绪的SaaS产品 SaaS产品加速器:基于Netbase成熟模块,快速构建AI就绪的SaaS产品

SaaS产品加速器是Netbase提供的一套可复用模块,涵盖账户、计费、权限与集成,帮助创始人和产品团队更快推出订阅制软件,并从首个版本起支持产品内AI功能。模块复用最多可缩短60%的开发时间,该方案已在Netbase自有的网络印刷SaaS产品Printcart上得到验证。

Learn More
line

与 Netbase 远程合作

Netbase 所有项目均远程交付,任何国家、任何行业的客户均可与我们合作;Netbase 已服务全球 80 个国家的客户。合同与发票由 Netbase JSC 开具,款项通过银行转账至 Netbase JSC 公司账户或 PayPal Business 支付。欢迎通过 WhatsApp 或邮件联系 CEO Huy Nguyen(David)。

联系 Netbase

讨论项目

Netbase JSC 帮助企业设计、构建、现代化和运营数字产品及 AI 驱动的业务系统。
项目咨询

project@netbasejsc.com

WhatsApp

+84 937 869 689

办公地址

91 Nguyen Chi Thanh, Dong Da, Hanoi, Vietnam

取得联系

告诉我们您想构建、现代化或运营什么。

告诉我们您想构建、现代化或运营什么。

联系 Netbase