我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
分解单体工作流程:模块化 Amazon Step Functions 工作流程
您可以使用 Amazon Step Functions 来协调复杂的业务问题。但是,随着工作流程的发展和演变,您可能会发现自己正在努力应对越来越难以维护和更新的单体状态机。在这篇文章中,我们向您展示了将大型 Step Functions 工作流程分解为模块化、可维护的组件的策略。我们深入研究了父子工作流程、基于域的分离和共享实用程序等架构模式,这些模式可以帮助您在维护业务功能的同时分解复杂性。通过实施这些解耦技术,您可以实现更快的部署、更好的错误隔离和更低的运营开销,同时保持工作流程的可扩展性和效率。无论您是处理支付处理、数据转换还是复杂的业务逻辑,这些模式都将帮助您构建更具弹性和可管理性的 Step Functions 应用程序。
单状态机器架构的复杂性
尽管单一工作流程可能适用于状态有限且依赖关系明确的简单线性流程,但在处理跨多个域的复杂业务逻辑时,它们会出现问题。如果您的工作流程涉及超过 15-20 个状态,跨越多个业务领域,或者需要不同团队的频繁更新,则有力地表明您应该考虑分解的方法而不是单一的方法。但是,对于具有简单业务逻辑、单一团队所有权、不经常更改以及状态少于 15 个的工作流程的场景,单一工作流程仍然是有效的选择,尤其是在优先考虑快速开发和简化调试的情况下。
让我们来看看这样一个单一工作流程的真实示例,了解它给开发团队、运营效率和业务敏捷性带来的挑战。以下是一个状态机示例,该状态机混合了电子商务实施的支付流程、库存管理和通知机制:
图 1:一种混合了电子商务实施的支付流程、库存管理和通知机制的状态机
状态爆炸
由于多个互连状态的紧密耦合和依赖关系,在单一工作流程中修改单一状态会触发一系列变化。例如,添加新的付款方式需要在各个状态进行修改,包括验证、处理和错误处理,从而在整个工作流程中产生连锁反应。这种相互依赖关系使即使是简单的更改也变得复杂而危险,因为更改一个组件可能会对工作流程的其他部分产生意想不到的后果。
从提供的架构来看,我们可以看到状态爆炸的明显例子,其中单个工作流程可以处理多个业务流程,包括订单验证、付款处理、库存管理、运费计算和客户通知。这形成了一个复杂的依赖状态网络,变得越来越难以管理。结果是状态的"蜘蛛网",越来越难以理解、调试和维护。
版本管理
单一工作流程中的版本管理需要部署整个工作流程,即使对单个组件进行了细微的更改,这使得隔离和更新特定的业务逻辑变得困难。提供的架构清楚地表明了版本管理的挑战。例如,如果运输计算逻辑需要紧急修复,则必须重新部署整个工作流程,要求对所有组件(包括未经修改的组件)进行全面测试,以确保流程中没有任何中断。
资源限制
虽然在架构图中无法立即看到,但随着复杂性的增加,Monolithic 工作流程面临操作限制,尤其是在状态转换、最大事件负载大小和执行历史记录大小方面。请参阅服务配额文档以了解此类限制。随着工作流程复杂性的增加和处理交易量的增加,这些限制成为关键瓶颈。在单体状态机中,支付处理和运费计算等长时间运行的操作,再加上多个状态转换,可能会接近这些极限,尤其是在高容量场景中。
此外,我们还遇到了诸如错误处理之类的通用设计挑战。在单一方法中,工作流程会导致冗余的 try-catch 区块和跨不同操作的重试配置。这给针对不同的业务场景实施不同的错误策略带来了挑战,并且使得在中间状态发生故障时很难维持适当的回滚机制。
这些挑战共同凸显了对 Step Functions 工作流程设计采用更加模块化的方法的需求。
通过分解改变复杂的工作流程
将复杂的单体工作流程转换为更易于管理的组件时,您可以采用多种分解策略来实现更好的模块化和可维护性。这些策略包括创建工作流分层结构的父子模式、根据业务能力分解工作流程的域分离、用作常见操作可重复使用组件的共享实用程序以及用于集中错误处理的专门错误工作流程。根据应用程序的特定要求和复杂性,这些策略可以单独实施,也可以组合实施,从而使组织能够创建更高效、可扩展和可维护的 Step Functions 工作流程,同时确保适当分离关注点并减少运营开销。
父子模式
父子模式代表了一种分层的工作流组织方法,其中主(父)工作流协调多个子工作流程(子工作流程)。父工作流程管理整个业务流程和协调,而子工作流则负责特定的短期操作。当您需要在编排复杂性和执行速度之间取得平衡时,这种模式尤其有效。
图 2:解耦的父状态机
可以通过创建专注于订单编排的父工作流程,同时将特定操作委托给 Express 子工作流程来重组当前的整体工作流程。父工作流程将保持从订单验证到完成的高级流程,而诸如 ValidateOrder、ProcessPayment 和 ProcessShipping 之类的时间敏感操作可能会变成快速子工作流程。
请注意,在架构改造期间,Express 工作流程与标准工作流程不同。例如,您不能让 Express 父工作流程调用标准子工作流程。此外,Express 工作流程不支持 Job-run (.sync) 或 Callback (.waitForTaskToken) 服务集成模式。您可以参考标准和快速工作流程文档之间的区别来选择正确的架构模式。
例如,付款处理部分可以转换为子级 Express 工作流程,将所有与付款相关的状态(ProcessPayment、流程标准支付、ValidatePaymentPart)作为一个单元进行处理。快速工作流程更适合付款处理等部分,因为它们的执行在 5 分钟内完成。因此,这也将降低工作流程的总体成本。同样,涉及 CalculateExpressShipping 和 CalculateStandardShipping 的运费计算逻辑可以合并到另一个 Express 子工作流程中,从而降低成本并更轻松地更新运输逻辑。
域分离
域分离涉及根据不同的业务能力或职能领域分解工作流程。每个特定领域的工作流程负责完整的业务功能,在通过明确定义的接口进行通信的同时独立运行。这种方法与微服务架构原理和领域驱动的设计非常吻合。该架构显示了不同业务领域之间的明确界限,可以将其分成独立的工作流程。出现了三个主要领域:
- 支付域:包括 ValidateOrder、ProcessPayment、ValidatePaymentPart 和相关的错误处理程序
- 库存域:包括 CheckInventory、UpdateInventory 和关联状态
- 配送域:包含流程配送、运费计算和配送状态更新
每个域名都将成为自己的工作流程,具有明确的输入/输出合同。这种分离将使专业团队能够独立维护和部署其域工作流程的更新,从而确保在不影响其他域的情况下实施特定域的重试策略、错误处理和业务规则。例如,付款团队可以在不影响运输或库存业务的情况下增强付款处理逻辑。
图 3:处理支付工作流程的子状态机
图 4:处理运输工作流程的子状态机
共享工具
共享实用程序工作流可作为可重复使用的组件,用于在多个业务流程中出现的常见操作。这些工作流程封装了通知处理、数据验证、记录或审计跟踪创建等标准功能。通过集中这些常见操作,组织可以确保其 Step Functions 应用程序之间的一致性并减少重复。
当前架构重复了几种常见模式,这些模式可以提取到共享实用程序工作流程中。最值得注意的是,通知处理逻辑(SendEmail、sendSmsNotification、sendPushNotification)在工作流程结束时显示为一组状态。这可以合并到一个处理所有类型通知的"通知管理器"实用程序工作流程中。然后可以从系统中的任何其他工作流程调用这些实用程序工作流程,从而确保行为一致并减少代码重复。
图 5:可重复使用的通知工作流程
错误工作流程
错误工作流程代表一种专门的分解形式,侧重于集中错误处理和恢复逻辑。组织可以创建专门的工作流程来管理不同类型的故障、重试和补偿行动,而不是在每个业务工作流程中嵌入复杂的错误处理。这种方法为处理应用程序中的错误提供了一种一致且可维护的方式。
根据应用程序的特定需求,每种分解策略都可以单独使用,也可以组合使用。例如,使用域分离模式简化了错误工作流程。关键是选择适当的组合,为您的用例提供可维护性、可扩展性和运营效率的适当平衡。但是,分阶段实施所有四种策略将为长期可维护性和可扩展性提供最全面的解决方案。
结果:
单片和解耦方法之间的比较表明,性能和运营指标存在显著差异。为了在单片和分解状态机上模拟类似的测试环境,我们在 us-east-1 亚马逊云科技区域对其进行了测试。我们利用上述工作流程,包括整体式和分解式工作流程来实现类似的最终目标。定价比较基于一个整体工作流程,每个工作流程处理 30,000 个月度请求中的 11 个状态转换。对于分解方法,计算假设 Express 子工作流配置有 64MB 的内存和 100 毫秒的执行时间,而父工作流程为每个工作流处理 8 个状态转换,处理相同数量的每月 30,000 个请求。两种方法中的 Amazon Lambda 任务状态都在执行时间后的 2 秒内完成。
解耦后,可以重新设计工作流程,使其根据执行时间和集成模式要求使用快速或标准机制。在这个用例中,我们确定了多个工作流程,例如付款处理、CalculateExpressShipping,这些工作流程经过了改进,可以根据要求使用快递工作流程。尽管整体方法的执行时间略快,为 11.5 秒,而分解方法的执行时间为 13 秒,但月度定价明显偏向于解耦架构,价格为 6.37 美元,而单片方法为 11.90 美元。与单片方法由于负载繁重和中间状态故障跟踪而面临的复杂调试挑战形成鲜明对比,这种解耦方法表现出卓越的调试能力、更好的错误隔离和特定域的调试。此外,解耦架构受益于通过分布式数据处理实现更小的有效载荷大小,而单片工作流程在其 18 个状态转换中承载更大的有效负载。
| 单片方法 | 解耦方法 | |
| 执行时长 | 11.5 秒即可完成工作流程执行 | 13 秒,跨父子工作流程进行分布式处理 |
| 月度定价 | 11.90 美元(476,000 美元可计费状态过渡) | 6.37 美元(标准家长工作流程和 Express 子工作流程的总成本) |
| 调试工作 | 高 — 由于负载繁重且难以跟踪中间状态的故障,因此调试非常复杂。当最终通知状态需要所有详细信息时,无法有效使用 ResultSelector。 | 更低 — 使用隔离域和较小的有效载荷更易于调试。更好的错误隔离和特定域的调试。 |
| 有效载荷大小 | 在整个工作流程执行过程中,有效负载大小更大,因为所有数据都需要在 18 个状态转换中传输 | 由于域分离和跨父子工作流的分布式数据处理,有效负载大小较小 |
结论
当您面临诸如状态爆炸、版本管理复杂性和资源限制等单一工作流程的挑战时,分解 Step Functions 工作流程的需求就显而易见了。这些挑战导致运营效率降低、调试复杂性增加和维护开销增加,比较结果显示执行时间、定价、调试工作量和有效负载管理存在差异。当组织观察到工作流程超过 15-20 个状态、多个团队参与工作流程维护、不同业务领域频繁的独立更新、复杂的错误处理要求以及需要跨工作流重复使用的组件时,组织应评估工作流程分解。通过分层工作流组织的父子模式、用于业务能力隔离的域分离、用于常见操作的共享实用程序以及用于集中错误处理的专用错误工作流程实施分解策略,在降低成本、更好的错误隔离和更有效的负载管理方面显示出了切实的好处。
在实施分解策略时,组织必须谨慎行事,避免工作流程过度分解,保持工作流程之间的紧密耦合,忽视松散耦合和单一责任的核心设计原则。这种工作流分解的战略方法最终带来了更具可维护性、可扩展性和更具成本效益的 Step Functions 应用程序,这些应用程序可以更好地满足业务需求,同时减少运营开销。从单一工作流程向分解工作流程的转变代表了重大的架构改进,使组织能够更好地管理复杂的业务流程,同时保持运营效率和系统可靠性。
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。