在现代应用程序开发领域,构建基于API驱动的微服务以实现可靠的业务流程,是一个极为常见的目标。像在线食品订购与配送、打车服务、在线金融交易以及电子商务订单处理等应用场景,都依赖这类微服务架构。然而,这种传统方法在实际应用中暴露出一些关键挑战,其中可靠性和一致性问题尤为突出。
可靠性困境
在基于API驱动的微服务架构里,业务流程的可靠性高度依赖于每一个微服务环节。由于采用同步API调用机制,整个业务流程就如同一条环环相扣的链条,其稳固程度取决于最薄弱的那一环。任何一个微服务出现故障,都可能像“黑天鹅事件”一般,导致整个业务流程瞬间中断。即便单个微服务的可靠性表现良好,例如达到99.95%(大致相当于每30天停机21分钟),但随着参与业务流程的微服务数量逐渐增多,端到端成功执行流程的概率会以指数级速度下降。以一个包含10个微服务的业务流程为例,其整体可靠性仅为0.9995¹⁰ = 99.5%,这意味着大约每30天就可能出现3小时36分钟的停机时间。为了缓解这一问题,开发团队可能会为每个微服务引入更多冗余,但这种做法不仅会大幅增加基础设施成本,而且并不能从根本上消除诸如网络故障等潜在风险。
一致性难题
当业务流程在执行过程中遭遇失败,而部分微服务调用已经成功完成时,一致性问题便接踵而至。这种情况会使分布式微服务之间的数据状态陷入不一致的混乱局面。在流程控制器中尝试实现回滚机制,往往会面临复杂的技术难题,而且一旦控制器本身出现故障,回滚机制也将形同虚设。在分布式环境下,调试和定位这些数据差异的来源,不仅需要耗费大量的时间和精力,而且通常需要开发团队进行手动修复,这无疑给运维工作带来了沉重的负担。
事件驱动架构:破局之道
面对上述困境,采用事件驱动的架构并结合协调模式,成为一种更为优化的解决方案。借助专门的工作流服务,通过异步事件来协调各个微服务,能够显著提升业务流程的可靠性和一致性。在这种架构下,即便个别服务出现停机状况,工作流也能在服务恢复上线后继续平稳运行,从而确保整个业务过程中数据的最终完整性。在本文中,我们将深入探讨如何借助Infinitic框架,从现有的API驱动微服务出发,构建稳健可靠的事件驱动业务流程。我们将详细剖析其架构模式、工作流实现细节以及部署过程中的考量因素,展示如何通过最小的投入,实现关键应用程序在可靠性和一致性方面的显著提升。
若你渴望在事件驱动应用和Infinitic领域抢占先机,不妨订阅https://infinitic.substack.com,以便及时获取该快速发展领域的最新动态。
构建基于API驱动服务的业务流程
利用API驱动的微服务构建可扩展的业务流 程,是一种备受青睐的方法。这些业务流程通常由面向客户的应用程序直接触发启动,或者通过定时任务(cron jobs)按照既定周期定期启动。
然而,这种看似完美的模式实际上存在两个主要弊端:
可靠性隐患
依赖多个微服务同步API调用的业务流程,就像一座建立在脆弱地基上的高楼,十分脆弱。由于流程的推进完全依赖于每个服务的成功响应,任何一个服务出现故障,都可能如同“多米诺骨牌”一般,导致整个流程瞬间崩塌。随着涉及的微服务数量不断增加,端到端的可靠性更是呈指数级下降。
一致性风险
当业务流程在执行过程中中途失败,而部分微服务调用已经成功完成时,一致性问题就会随之而来。这可能导致系统的数据状态处于不一致的混乱状态,数据更新分散在不同的服务之中。在流程控制器中实现回滚机制,不仅技术难度极大,而且一旦控制器自身出现故障,回滚机制也将无法发挥作用。在分布式环境下,调试和理解这些数据差异的来源,既复杂又耗时,通常需要开发团队投入大量精力进行手动修复。
使用消息代理
采用基于消息代理的事件驱动异步通信模型,为解决上述问题提供了新的思路。在这种架构下,服务之间不再通过直接的内存中的HTTP请求进行交互,而是将事件发布到由消息代理提供的持久化消息队列中。其他服务则在准备就绪时,主动从队列中拉取并消费这些事件。这种解耦的消息驱动架构,通过将数据持久化直至被消费,极大地增强了系统的可靠性,有效避免了因服务停机而导致的故障。此外,它还能够通过缓冲请求,避免服务因峰值负载而过度扩容,从而降低运营成本。
这一目标通常通过编舞模式来实现。编舞模式是一种事件驱动系统的架构风格,在这种风格下,每个微服务都能根据其他服务发出的事件做出响应并采取相应行动。基于事件的处理方式,不仅解决了可靠性问题(即便服务停机,恢复后仍能继续运行),还有助于解决一致性问题,因为工作流最终能够完成,即使在执行过程中遇到暂时性问题。
然而,尽管这种方法在简单场景中表现出色,但随着业务流程变得越来越复杂,涉及条件逻辑、超时处理和错误处理等复杂情况时,其编码、维护和监控的难度也会随之急剧增加。
在我们构建事件驱动应用的方式被误导一文中,我详细阐述了为何更倾向于协调模式。协调模式是事件驱动系统的另一种架构方式,其中专门的工作流服务充当中心协调者的角色,负责协调业务流程中涉及的各个微服务。该服务不仅负责启动流程流,还管理事件和服务调用的顺序,并在必要时处理错误或进行重试操作。与编舞模式相比,协调模式极大地简化了复杂事件驱动流程的开发和维护工作,同时提供了更好的可观察性和控制能力。
在上述文章中,我还介绍了Infinitic,这是我主导开发的一个框架,旨在实现不可中断的事件驱动应用的中央协调功能。
Infinitic提供的关键组件在下图中以绿色标识:
- 客户端:作为启动和与业务流程进行交互的入口。
- 服务工作者:这些是专门负责执行特定服务的工作者。每个服务工作者能够在Apache Pulsar上发布和消费与其服务相关的事件,并承担错误管理的职责。
- 工作流工作者:它们是整个架构的中央协调组件。负责管理整体业务流程流,通过发布和消费事件来协调各个服务的执行过程。
目前,Infinitic采用Apache Pulsar作为底层消息系统。
使用Infinitic具有诸多显著优势:
- 卓越的横向扩展能力:能够轻松应对业务增长带来的高并发需求。
- 出色的弹性:内置的错误管理机制(包括重试、死信队列、错误传播等),使系统具备强大的容错能力。
- 复杂业务流程支持:能够支持编写更为复杂的业务流程,例如包含定时器或信号等功能。
- 集中化与版本化管理:实现工作流定义的集中化管理,并支持Git版本控制,方便团队协作开发和维护。
- 无缝流程更新:具备在不影响正在运行的工作流的前提下,对流程进行更新的能力。
- 内置可观察性:为工作流状态提供了内置的可观察性,便于实时监控和问题排查。
使用Infinitic实现业务逻辑
Infinitic赋予开发者使用熟悉的Java或Kotlin编程语言来定义与协调业务工作流的能力。开发者无需额外学习特定领域语言(DSL)去描述工作流,而是能够借助已有的代码与分布式微服务展开交互,整个执行过程遵循事件驱动机制。这种低门槛的特性,使得开发者既能轻松地从头开始编写全新的基于事件的工作流,也可以将现有的同步控制器重构为稳健的异步工作流。
以一个简单的订阅服务月度计费流程为例。当用户完成服务订阅操作,该流程随即启动。此后,系统会开启一个循环机制,在每月月初自动检查用户的订阅状态。若用户仍处于订阅状态,便会依序执行以下一系列步骤:
- 等待至下个月;
- 调用
ConsumptionService::get
方法获取消费数据; - 调用
PaymentService::request
方法请求付款; - 调用
InvoiceService::create
方法创建发票; - 调用
EmailService::send
方法通过电子邮件发送发票。
完成邮件发送后,循环将再次启动,继续检查用户在下个月是否依然保持订阅。一旦检测到用户未订阅,流程便会退出循环并宣告结束。
以下是以Kotlin语言实现该工作流的代码示例:
可以看到,这段代码与在业务流程控制器中编写的代码极为相似,区别仅在于此代码所控制的是一个事件驱动流程。
Infinitic提供的newService
函数,以服务接口作为输入参数,并返回该接口的模拟实现。当对这个模拟接口的某个方法发起调用且对应一个新请求时,Infinitic会分发一个事件,以此触发相应服务的执行操作。而若该方法调用的结果此前已被处理过,Infinitic则会直接从其事件日志中返回预先计算好的结果。
若您对其内部工作原理感兴趣,可阅读事件驱动“代码即工作流”引擎的幕后一文。
使用您的API创建事件驱动服务
Infinitic贴心地提供了现成可用的服务工作者,开发者只需专注于提供服务实现即可:
- 为业务流程中所使用的服务定义Java(或Kotlin)接口;
- 编写上述接口对应的Java(或Kotlin)实现代码。通常情况下,这段代码会调用您API中的不同方法。需特别注意的是,在调用失败时务必抛出异常,如此方能确保Infinitic能够顺利进行重试操作;
- 将此实现应用于Infinitic的服务工作者。
部署您的事件驱动流程
要成功部署新创建的事件驱动流程,需依循以下步骤:
- 部署实现业务流程的工作流工作者;
- 部署负责处理API调用的服务工作者;
- 设置一个Apache Pulsar实例。值得一提的是,Infinitic全面管理与Pulsar相关的所有方面,涵盖主题拓扑、设置、架构管理以及消费者/生产者实现等。所以,即便您此前没有Pulsar相关知识储备,也完全不妨碍使用Infinitic。若您不想自行搭建Pulsar,还可选用StreamNative、DataStax或CleverCloud等公司提供的托管Pulsar实例。
通过遵循上述步骤,您的业务流程将成功转变为事件驱动模式,在充分利用现有API驱动服务的同时,确保流程具备卓越的可靠性与一致性。而且,这种转变所需投入的精力极少,短短几周便可完成,而非传统方式所需的数月时间。
关于代码生成的更多思考
若您的服务通过IDL(如用于REST API的OpenAPI,或用于远程过程调用的gRPC)得到了清晰明确的定义,那么创建Infinitic的服务工作者这一过程完全可以实现自动化。凭借明确的服务定义,代码生成工具能够解析服务契约,并自动生成在Infinitic的服务工作者中调用服务所需的样板代码。
这一举措将极大地简化现有API驱动微服务与Infinitic编排框架的集成流程,既能大幅减少人工工作量,又能将出错风险降至最低。目前,我正朝着这一方向探索,期望作为未来的一项重要增强功能,为采用Infinitic和现有微服务的开发者打造更为无缝的入门体验。此外,该方法对那些不想使用Java、Kotlin的团队而言,也不失为一大福音。
结论
利用API驱动的微服务构建既可靠又一致的业务流程,向来是一项颇具挑战性的任务。不过,采用Infinitic的事件驱动编排方法,能够显著降低可靠性和一致性方面出现问题的风险。
Infinitic通过借助现有API驱动微服务来开发事件驱动的业务流程,为开发者提供了一套强大的解决方案。运用Infinitic的工作流实现方法,开发者能够构建出具备内在弹性、可扩展性以及可维护性的全新业务流程。通常而言,仅需短短几周时间,便能完成原本从头构建类似功能需数月才能达成的工作。
使用Infinitic进行事件驱动业务流程开发,具有诸多关键优势:
- 通过异步事件驱动通信以及服务故障后的平稳恢复机制,大幅提升可靠性;
- 即便在流程中途遭遇失败,也能有效维持分布式系统中的数据一致性;
- 借助Infinitic的工作流实现方法,极大地简化复杂业务流程的开发与维护工作;
- 具备出色的横向扩展能力;
- 内置强大的错误管理能力;
- 支持在不中断正在运行流程的前提下,对工作流进行更新与版本控制;
- 增强了工作流状态的可观察性,为监控与调试工作提供便利。
通过采用Infinitic,您能够为关键任务的业务流程筑牢未来发展的根基,确保它们在组织不断发展壮大的过程中,始终保持可靠、一致且具备良好的扩展性,彻底摆脱传统API驱动方法的种种限制。
将API驱动的微服务转变为事件驱动架构。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。
文章由技术书栈整理,本文链接:https://study.disign.me/article/202510/9.api-based-microservices-to-event-driven-architecture.md
发布时间: 2025-03-04