在最近的blog中,A16Z讨论了现代交易堆栈的状态,并将Orkes导体称为现代交易后端的重要框架之一。该文章讨论了应用程序开发平台的当前状态和格局,这些平台提供了开箱即用的交易管理功能。在本文中,我们研究了两种主要方法 - 面向数据库和面向工作流的交易后端 - 并讨论了利用它们的应用程序的架构,并权衡了两种方法的利弊。 P>
现代应用程序开发状态
所有现代应用都是分布式系统。在现代应用程序中,不同的组件或服务通常需要共同努力,以提供无缝的用户体验。例如,移动应用程序可能需要与后端服务进行通信以检索数据或处理用户的请求。这需要应用程序和服务才能通过网络交换信息,这是分布式系统的关键特征。
此外,现代应用程序通常依赖于云计算和其他基础架构服务,例如数据库,消息队列和缓存系统,这些系统是由本质上分发的。这些服务提供了关键功能,例如可伸缩性,容忍度和高可用性,所有这些服务对于满足全球受众的需求至关重要。
现代应用程序的分布式性质使它们更加灵活,可扩展和弹性,这就是为什么它们已成为现代企业软件开发的首选架构。
将此与传统的企业应用程序进行比较,在数据库事务中执行了客户端的所有请求,以及满足应用程序需求所需的所有数据都位于单个应用程序的特定数据库中。这效果很好,但创造了一种整体模式,从长远来看,很难扩展,变化且难以维护。同样,还有一个问题的问题是,长期运行的工作流程可能跨越几天甚至数月的时间,维护申请交易的问题仍然需要数据库不提供的解决方案。
这带来了一个重要的问题 - 如果您采用正在运行分布式服务的应用程序体系结构,则如何处理跨越多个服务的交易?
交易,保证和现代应用程序(所有交易都相等吗?)
考虑订单管理系统:
具有多个服务的应用程序具有两种类型的交易:
- 服务本地的:生成顺序上面的步骤在系统中创建一个新订单,并将详细信息插入订单表中。
- 应用级别交易:控制整个应用程序流的交易。在上面的示例中,我们有一个交易,该交易开始在订单被放置并在流程终止时完成。两者之间的任何持久失败都必须在特定于服务的数据库中逆转。
分布式系统的一致性
我们希望这些系统在世界状态下保持一致。但是,在分布式系统中,这通常很难实现,给定多个因素,并且需要协调可能会持续数天的单一交易。
在传统数据库的系统中,数据库充当交易协调器,提供了数据库提供的一致性级别。但是,这仍然无法解决长期运行和异步流的情况,在这些情况下,交易需要从乐队中更新并根据业务要求进行管理。
工作流引擎作为分布式交易后端
分布式事件驱动的应用程序中的工作流程使服务可以通过事件相互通信,从而使其成为应用程序状态的真实源。诸如Orkes导体之类的编排者是维护应用状态并处理分布式交易的集中协调员。这通常称为 saga模式。
传奇模式的核心思想是,长交易被分成由交易协调员(例如Orkes导体)协调的短交易。如果每个简短的交易操作都成功完成,则全局交易正常完成,如果步骤失败,则每次以相反顺序调用补偿操作。
这种方法大大简化了长期运行的分布式交易的管理以及在多个服务中管理应用程序状态的问题。
在长期运行过程中的分布式系统和交易
管理长期运行的交易通常需要不同的策略来处理回滚或补偿的模式。回滚通常是通过通过补偿反转本地交易来完成的。回滚的内容,相关的补偿通常取决于交易的当前状态。
例如,在我们的订单管理系统中,如果交货失败,薪酬逻辑可能是在信用卡上签发退款,将电子邮件发送给通知情况的用户并更新数据库中的订单状态。
未能处理信用卡交易可能意味着取消订单并向用户发送电子邮件。
使用诸如Orkes导体之类的平台,这是通过薪酬工作流进行处理的,这些薪酬工作流是由于系统错误或业务案例验证失败(库存不足)而触发时会触发的。工作流引擎在这里有两个目的:
- 工作流程是应用状态的真理的来源。可以查询工作流程系统以在任何时候获得交易的状态,并且它将在多个服务及其本地后端充当聚合器。在订单管理示例中,我们可以向系统询问订单ID的状态,它将确切地告诉我们订单状态是什么以及与哪种服务。
- 工作流充当分布式交易协调员。如果特定步骤必须在过程中失败,则系统按照蓝图中指定的运行补偿逻辑来处理运行薪酬逻辑。
应用状态与商业状态
典型应用程序将具有两种状态:
- 应用程序状态:这定义了程序定义的应用程序流的状态,以实现特定目标,例如过程顺序。
- 业务国家:通常管理业务实体状态 - 例如,订单的交付状态。您可能有多个正在更新或阅读业务状态的应用程序流。
这两个状态通常是分离的。作为本地交易的一部分,应用程序流程通常会通过应用程序流以其工作流程的一步进行更新。
以数据库为中心的交易堆栈
一种方法是使用以数据库为中心的堆栈,该堆栈允许您从数据库事务管理应用程序和业务状态。这种方法具有简单性的优点,因为您可以使用管理整个状态的数据库编写整个应用程序。
这种方法从哪里开始分解?
虽然简单,但随着应用程序逻辑开始变得更加复杂,它会分解。但是,这种方法有几种弊端:
- 今天的大多数平台都专注于打字稿/JavaScript作为编写逻辑的语言,该语言限制了您可以使用的库生态系统。
- 该体系结构在UI驱动的应用程序和简单的CRUD应用程序中非常好;但是,对于应用程序集成和长期运行过程,您通常必须与其他系统集成。
- 处理长期运行的交易仍然需要实施策略来处理薪酬和应用特定逻辑到回滚交易。
- 很难与外部系统实施许多企业集成模式。
- 真理的单一来源最终对单个数据库系统产生了整体依赖性,因此很难随着业务复杂性而扩展。例如,管理公司核心订单管理系统的单个DB可能不是企业的理想解决方案。
- 管理代码中的整个业务流程使得更难可视化进度并通过增加系统中存在问题的同时检测和维修来使调试流程变得复杂。
Orkes指挥 +业务州经理
工作流引擎与业务状态管理工作者一起工作的架构并不是什么新鲜事,我们利用了Netflix在多个应用程序中成功地在Netflix上进行了架构,在这些应用程序中,导体维护了应用程序状态和专职工人在数据库中管理业务状态。 (但是,该部分不是开源的)。
在此体系结构中,一组负责维持业务状态的专门工人正在聆听应用程序工作流程状态并创建必要的数据库交易以反映业务状态。例如,当工作流启动时, onStart 事件将插入数据库中的订单ID的新订单,而工作流程完成时,oncomplete事件会更新状态。在这种情况下,状态听众是数据库表的写作来源,任何人都可以在工作流程外阅读。
工作流 +业务州经理更好地工作的原因:
虽然起初看起来似乎很复杂,但该方法随着业务的复杂性和增长而良好。
- 使用多语言语言/框架选择的更大选择开发生态系统
- 将业务逻辑和状态管理与数据库的解耦以及如何/在何处存储业务状态。
- 能够独立扩展组件,并能够创建具有域名的服务/组件的更大可重复使用。例如,平台团队可以拥有和扩展客户联系服务(电子邮件,SMS),而不是与他们一起使用的用例(订单管理,营销等)。 。
- 处理业务状态的数据库可以是多模型,从传统的关系数据库到NOSQL,以及用于ML Workloads的图形或矢量数据库等专业数据库。
结论
将以数据库为中心方法的语义结合到工作流程中会产生强大的组合,从而可以轻松构建非常复杂和可扩展的分布式应用程序。我们认为,这种方法在处理业务复杂性以及应用使用情况增长方面提供了两全其美的最佳状态。
在orkes.io和https://github.com/Netflix/conductor的开源Netflix导体中查看我们。