从分布式单体到AWS可组合架构的转型指南

本文深入探讨如何通过领域驱动可组合架构解决分布式单体问题,详细介绍在AWS上构建独立可组合微服务的技术模式,包括EventBridge、Step Functions和DynamoDB Streams等服务的实际应用。

从分布式单体到AWS可组合架构

问题:技术边界创建分布式单体

微服务承诺了独立部署和团队自治,但大多数企业未能实现这些好处。原因是边界围绕技术层或组织便利性绘制,而不是业务领域。这反映了对分解的根本误解。

在信用卡奖励处理中,架构团队可能创建单个RewardsService,处理商户分类、赚取率计算、促销奖金、里程碑跟踪和积分分类账,所有这些都捆绑在一起,因为它们被认为是"奖励逻辑"。当商户类别代码每季度更新时,整个服务重新部署,需要跨不相关模块进行全面回归测试。

结果是具有负载均衡器、部署和云集群的分布式基础设施,与共享数据库、协调发布和级联故障等单体耦合相结合。结果是继承了分布式系统的复杂性,而没有获得真正的独立性。

解决方案:业务驱动的边界

领域驱动可组合架构(DDCA)应用领域驱动设计原则,按业务能力定义服务边界。有界上下文定义了清晰的业务领域,其中奖励处理与交易授权根本不同。这些边界成为打包业务能力(PBC),是可独立部署的自治单元,代表离散的业务功能,实现真正的服务独立性。

从图1到图2的转变代表了从技术耦合到业务独立的转变。在单体架构中,单个部署单元强制所有五个能力一起扩展、部署和失败。在PBC架构中,每个能力作为自己的Lambda函数运行,具有专用的DynamoDB表,Step Functions替换负载均衡器作为编排层,仅为每个卡产品调用所需的能力。

工作流组合

奖励编排器(图2中的Step Functions)从独立的PBC组合工作流。高级卡调用所有五个PBC,如商户分类、赚取率引擎、促销乘数、消费里程碑跟踪器和积分分类账。基本返现卡仅调用商户分类和积分分类账,采用固定费率。这种可组合设计允许快速引入新产品和活动。

PBC设计实践

PBC遵循三个不可协商的原则:

  • 数据所有权:PBC完全拥有其数据。没有跨PBC的直接数据库访问。所有交换通过接口或事件进行
  • 清晰接口:PBC可以通过API同步调用,或在工作流内直接作为Lambda函数调用。它还可以发布域事件供异步消费者使用
  • 单一团队所有权:一个自治团队端到端拥有部署、测试和扩展

何时采用DDCA

DDCA是强大但资源密集的方法。它最适合具有复杂业务域和长期敏捷性需求的系统。

使用DDCA当:核心业务有复杂逻辑(如银行或保险),正在推动大规模企业现代化,或多个独立团队与业务能力对齐

避免DDCA当:应用程序是简单的CRUD系统,挑战主要是技术而非业务复杂性,或团队小而缺乏领域驱动设计专业知识

运营现实

采用DDCA需要显著的运营成熟度。从单个RewardsService移动到多个独立可部署的PBC增加了要管理的组件数量,这提高了对自动化、规范测试和强大可观测性的需求。与单体相比,预计在监控和基础设施方面会有更高投资。

AWS实现:将DDCA映射到AWS服务

DDCA概念 AWS服务 技术模式 业务价值
自治PBC Lambda, ECS Fargate 每个业务能力独立部署 部署商户分类而不触及促销乘数
解耦通信 EventBridge 事件驱动架构(通过事件发布/订阅) 促销故障不阻塞基础奖励处理
弹性编排 Step Functions 带回退的错误处理;带补偿的Saga模式 费率查找失败使用基础费率,交易继续
数据一致性 DynamoDB, DynamoDB Streams, Lambda, EventBridge 事务性发件箱(写入业务行和发件箱,通过流发布;至少一次) 分类账写入和发件箱原子持久化;通过流重试发布(至少一次)
安全隔离 IAM, 可选的VPC或按上下文账户 每个PBC能力的最小权限(零信任) 基础卡编排器不能调用高级PBC

AWS实战手册:可组合架构的三种模式

模式1:事件驱动通信(解耦PBC)

在单体中,一个组件故障可能使整个系统崩溃。事件驱动架构解耦PBC,因此如果下游能力不可用,上游PBC继续处理并发布事件供以后消费。这避免了级联故障并保持部分可用性。

PBC通过Amazon EventBridge发布域事件,而不是同步服务调用。EventBridge提供模式管理、事件过滤和跨账户交付,使其更适合大规模可组合性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
await eventBridge.putEvents({
  Entries: [{
    Source: 'rewards.merchant-classification',
    DetailType: 'MerchantCategorized',
    Detail: JSON.stringify({
      transactionId: 'txn-12345',
      merchant: 'Sample Merchant',
      category: 'retail',
      confidence: 0.95
    })
  }]
});

如果促销乘数服务关闭,基础奖励仍会立即计入。促销奖金在服务恢复时应用。

模式2:使用Step Functions的弹性编排

跨PBC的分布式事务难以可靠实现。AWS Step Functions协调多个PBC工作流,具有显式错误处理。当步骤失败时,工作流应用回退以保持可用性并防止级联故障。

例如,如果赚取率查找失败,工作流应用基础费率而不是使交易失败。对于需要反转已完成步骤的场景,Step Functions还可以通过补偿动作实现saga模式。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "StartAt": "ClassifyMerchant",
  "States": {
    "ClassifyMerchant": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:merchant-classification-pbc",
      "Catch": [
        { "ErrorEquals": ["ClassificationFailed"], "Next": "UseDefaultCategory" }
      ],
      "Next": "CalculateEarningRate"
    },
    "UseDefaultCategory": { "Type": "Pass", "Next": "CalculateEarningRate" },

    "CalculateEarningRate": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:earning-rate-engine-pbc",
      "Catch": [
        { "ErrorEquals": ["RateLookupFailed"], "Next": "ApplyBaseRate" }
      ],
      "Next": "CreditPoints"
    },
    "ApplyBaseRate": { "Type": "Pass", "Next": "CreditPoints" },

    "CreditPoints": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:points-ledger-pbc",
      "End": true
    }
  }
}

模式3:事务性发件箱(数据一致性)

没有原子保证,PBC可能更新其数据库但未能发布事件,使其他PBC具有过时数据。事务性发件箱模式通过使用DynamoDB TransactWriteItems在一个原子操作中写入业务变更和发件箱记录来解决此问题。Lambda函数通过DynamoDB Streams读取发件箱并发布到EventBridge。这提供至少一次交付,无需分布式事务。消费PBC必须处理重复事件,因为同一事件可能被多次传递。

安全:PBC边界的零信任

安全性在能力级别执行,使用零信任模型验证每次调用并授予最小权限访问。每个PBC仅暴露需要的内容,调用者通过身份和策略而非网络位置授权。这防止跨能力级联泄露并减少爆炸半径。

  • 显式验证:每次调用都经过身份验证和授权;每次调用PBC时评估IAM
  • 最小权限:服务角色仅允许对特定PBC的特定操作
  • 遏制:每个PBC被隔离;可选的VPC或账户分离在不改变接口的情况下加强边界
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "Statement": [{
    "Effect": "Allow",
    "Action": "lambda:InvokeFunction",
    "Resource": [
      "arn:aws:lambda:merchant-classification-pbc",
      "arn:aws:lambda:points-ledger-pbc"
    ]
  }]
}

此策略附加到基础卡编排器的执行角色,允许其仅调用商户分类和积分分类账,而不是赚取率引擎或促销乘数。如果编排器被泄露,攻击者无法访问高级卡能力。

避免陷阱:三种DDCA反模式

即使有良好意图,团队也经常陷入取消DDCA好处的模式。这些陷阱重新创建了你试图逃避的分布式单体。

  1. PBC间共享数据库:最具破坏性的反模式。例如,如果商户分类和赚取率引擎都查询相同的奖励数据库表,你在数据层就有紧耦合
  2. 具有业务逻辑的编排器:编排器应仅协调。如果奖励编排器开始决定应用哪些促销或计算奖金阈值,业务逻辑已泄漏到PBC外部
  3. 过度碎片化:将能力拆分得太细会增加网络 chatter 和运营开销,而没有增加真正的业务价值

超越代码:组织和业务影响

领域驱动设计方法使技术架构与业务结构对齐,创建强大的组织优势。

  • 团队结构:团队与业务有界上下文对齐,如奖励处理小队
  • 产品敏捷性:产品负责人可以直接从现有打包业务能力组合新卡产品或奖励流,而无需等待多个团队
  • 策略和审计:业务策略变更,如奖励资格或促销规则更新,被隔离到受影响的特定PBC

从单体到PBC的绞杀者模式迁移

从最高价值的PBC开始。在奖励处理中,商户分类是一个强有力的候选者,因为它随MCC更新频繁更改,具有清晰的输入和输出,并在独立部署时提供快速胜利。在单体旁边构建此PBC,将少量流量转移到它,并在四到六周内逐步增加,同时监控准确性。仅在建立完全信心后停用遗留代码。

结论

打包业务能力将分布式单体转变为真正的可组合架构。通过使技术边界与业务能力对齐,并将它们映射到EventBridge、Step Functions和DynamoDB Streams等AWS服务,团队可以减少耦合并加速交付。当部署周期从数周缩短到数天,审计范围缩小到单个模块,新产品可以通过组合现有能力而不是重写代码来组装时,回报是可衡量的。

可组合性不是使服务变小;而是使它们可互换。通过有意的边界和规范执行,组织可以超越意外耦合,实现持久的敏捷性。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计