StackSaga 同步引擎 (Stacksaga Synchronous Engine)

StackSaga 同步引擎 (Stacksaga-Sync Engine) 是构建在 Spring Boot 之上的响应式 Saga 编排引擎框架。

它使开发者能够通过协调主执行操作及其对应的补偿操作来设计和管理复杂的分布式工作流,通过 Saga 设计模式有效解决分布式系统中的最终一致性挑战。

StackSaga 同步引擎架构支持实现您选择的任何同步通信风格 —— 例如 REST(基于 HTTP)、gRPC(基于 HTTP/2)或 GraphQL(基于 HTTP)—— 赋予您足够的灵活性,以最适合系统需求的方式集成微服务。

以下是 StackSaga 提供的部分核心功能特性:

尽管 StackSaga 同步引擎在底层采用响应式机制运行,但它完全兼容*响应式 (Reactive)* 与*非响应式 (Non-Reactive / Imperative)* Spring 环境。
  • 用于管理主执行流程与补偿工作流的 Saga 编排引擎 (Saga Orchestration Engine)。

  • 双重长事务 (LRT) 模型:同时支持 连续型长事务 (Continuous LRT)(不间断的直通执行)与 可暂停长事务 (Pausable LRT)(业务条件等待状态,通过 stepManager.pause() 与 SagaTemplate.resume() 进行回调关联)。

  • 分布式事务协调 (Transaction Coordination)。

  • 幂等性保障 (Idempotency)(确保多次重复执行同一操作具有与执行一次完全相同的效果,这对高可靠性至关重要)。

  • 事务异步自治重试 (Asynchronous Retrying)。

  • 事件溯源与状态管理 (Event Sourcing & State Management)。

  • 分布式事务追踪监控:通过 StackSaga Trace-Window 进行图形化全链路追踪。

  • 高并发控制 (Concurrency Control) 等等……

StackSaga 组件概览 (High-Level Overview)

在 StackSaga 生态系统中,多个组件紧密协同工作。 根据使用职责,可划分为以下几个部分:

下图展示了各组件之间的依赖关系及其在 StackSaga 生态系统中的协作方式:

StackSaga 组件概览

核心组件说明:

  • stacksaga-spring-boot-starter 提供 StackSaga 框架的核心功能,如 Saga 工作流管理、事务协调、幂等性、事件溯源等。

  • stacksaga-db-support 为 StackSaga 框架提供事件存储 (Event Store) 支持实现,并提供用于从 StackSaga Trace-Window 访问追踪详情的内部 REST API。

  • stacksaga-env-support 在云环境中向 SEC 提供与环境相关的地理元数据(区域、可用区、实例 ID 等)。

  • Agent 服务 / 重试节点 作为独立应用或侧车为编排服务提供分布式事务重试管理。

  • StackSaga Trace-Window 提供事务的端到端可视化监控设施(由云端托管,无需额外开发)。

StackSaga 的一个关键架构优势在于您绝不需要部署专属或独立的中心编排服务器。 相反,StackSaga 遵循以业务域为中心(服务内嵌式)的编排 (Domain-Centric / Service-Embedded Orchestration) 模型:

  • 无需专用编排器基础设施:您不需要构建或部署单独的“编排微服务”。任何标准微服务只需添加 StackSaga 组件即可成为编排器。

  • 按业务领域去中心化集中:

    • 对于订单下单工作流,将 StackSaga 组件添加到 order-service 中。order-service 即成为该订单域的中心编排器。

    • 如果您的系统还包含复杂的多步支付结算、退款或对账 Saga,只需将 StackSaga 组件添加到 payment-service 中,使其成为支付域的编排器。

    • 单个微服务可以在其限界上下文内编排一个或多个业务领域。

  • 下游服务零变更:由编排器调用的微服务(例如 user-service 或 inventory-service)保持为标准实用服务,零 StackSaga 依赖。

stacksaga-spring-boot-starter 依赖项

stacksaga-spring-boot-starter 是框架的核心,可作为依赖项引入您的项目中:

<dependency>
  <groupId>org.stacksaga</groupId>
  <artifactId>stacksaga-spring-boot-starter</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

stacksaga-spring-boot-starter 协同以下核心组件工作:

stacksaga-db-support 依赖项

StackSaga 依赖事件存储 (Event Store) 运行。 因此,它需要针对目标数据库的支持模块实现。 所选用的数据库实现取决于目标编排服务的主数据库。 例如,如果您希望在 order-service 中配置 StackSaga,并且 order-service 使用 MySQL 作为主数据库,则需要在 order-service 中添加名为 stacksaga-mysql-support 的依赖项。

目前提供以下数据库实现:

stacksaga-env-support 依赖项

stacksaga-env-support 依赖项为 SEC 提供与环境相关的地理元数据(区域、可用区、实例 ID 等)。 根据应用程序的部署环境选择相应的模块。 例如,如果将 order-service 部署在 Eureka 环境(基于 Eureka 的服务发现与负载均衡)中,需要在 order-service 中引入 stacksaga-eureka-support。 如果希望将其迁移到 Kubernetes 环境,可将依赖项切换为 stacksaga-k8s-support。

目前,StackSaga 通过实例区域解析支持多种云和容器环境(参见 实例区域解析与 SagaRegionResolver)。

为了管理分布式事务重试,StackSaga 使用通过令牌环分区协调的重试子系统。 有关完整的部署和配置细节,请参阅 重试子系统架构。

StackSaga Trace-Window 监控平台

StackSaga Trace-Window 是一个能够以图形化方式直观查看事务链路详情的观测平台。 该组件无需开发者编写额外实现代码,您可以直接访问 trace.stacksaga.org 并进行使用。

底层架构图 (Low-Level Diagram, LLD)

下图展示了 StackSaga 执行协调器 (SEC) 如何融入 StackSaga 的整体架构体系中:

StackSaga 框架中的 StackSaga 执行协调器 (SEC)
  1. 请求到达编排服务,并交由 SEC 进行异步或响应式处理。

  2. SEC 获取该请求,并从配置的起始点启动流程执行。

  3. 在 stacksaga-database-support 模块和 stacksaga-env-support 模块的协助下,各步骤根据编程式导航逐一执行,同时将状态保存在事件存储中,以便于后续重试和追踪。

  4. 如果发生任何主执行失败,SEC 将以逆序触发对应的补偿执行操作。

  5. 如果在补偿执行期间因资源不可用发生失败,SEC 将使事务进入重试模式,并根据配置的重试策略自动重试。

  6. 配置的 Agent 服务 / 重试节点定期检查处于重试模式的事务,并通过调用编排服务内置的重试端点进行重新调度。

  7. SEC 再次接管请求,从事件存储中恢复先前的快照状态,并从失败点继续执行。

  8. 事务的每次状态更新均保存在事件存储中,且 SEC 在状态变更时向配置的监听器发布事件。

  9. 管理人员可以通过访问 StackSaga Trace-Window,利用 stacksaga-database-support 模块提供的端点以图形化方式审查事务执行轨迹。

自定义配置 (Custom Configurations)

StackSaga 提供了根据实际业务需求定制高级特性的灵活性。

Saga 调度器配置 (Saga Scheduler Configuration)

StackSaga 框架(同步实现)为 Saga 执行提供了默认的调度器配置,该配置使用 Project Reactor 的 BoundedElastic 调度器。 除非您提供自定义实现,否则将自动应用此默认配置。

默认配置规范 (Default Specifications)

默认调度器由 StackSagaSyncAutoConfiguration 类提供,无需额外设置。

参数 默认值

调度器类型

BoundedElastic

线程池大小

availableProcessors() × 10

队列容量

100,000

线程名称前缀

saga-exe

线程空闲超时

60 秒

守护线程 (Daemon Threads)

false

默认行为示例

在具有 4 个 CPU 核心的系统上,默认配置的行为如下: - 最大线程池大小:40 个线程 (4 × 10) - 队列容量:100,000 个任务 - 空闲线程超时:60 秒后释放线程 - 线程为非守护线程(如果有待处理任务,将阻止 JVM 退出)

自定义调度器 (Customizing the Scheduler)

要自定义调度器行为,请在项目的 Spring 上下文中声明自定义的 AbstractSchedulerProvider Bean。框架将自动检测并使用它替代默认实现。

实现指南
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.stacksaga.util.AbstractSchedulerProvider;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

@Configuration
public class CustomSchedulerConfiguration {

    @Bean
    public AbstractSchedulerProvider customSchedulerProvider() {
        return new AbstractSchedulerProvider() {
            @Override
            protected Scheduler scheduler() {
                return Schedulers.newBoundedElastic(
                    50,              // 自定义线程池大小
                    50_000,          // 自定义队列容量
                    "custom-saga",   // 自定义线程名称前缀
                    120,             // 自定义超时时间(秒)
                    true             // 是否为守护线程
                );
            }
        };
    }
}
定制参数说明
AbstractSchedulerProvider 是抽象 Reactor Scheduler 创建的模板类。您可以定制以下任意参数:
  • 线程池大小 (Thread Pool Size):池中维护的线程数量。

  • 队列容量 (Queue Capacity):允许积压的最大待处理任务数。

  • 线程名称前缀 (Thread Name Prefix):线程名称的前缀(有助于排查问题与监控)。

  • 空闲超时 (Idle Timeout):空闲线程终止前的等待时间(秒)。

  • 守护标志 (Daemon Flag):线程是否应为守护线程。

最佳实践
自定义配置时请注意以下考量:
  • 根据预期的 Saga 并发吞吐量调整线程池大小。

  • 队列容量应合理配置以应对突发峰值流量,避免引发 OutOfMemoryError。

  • 谨慎使用守护线程 —— 默认的非守护线程可确保应用优雅停机 (Graceful Shutdown) 时未完成的任务不会丢失。

  • 密切监控线程利用率,以便进行合理的容量评估。

  • 在特定生产环境中对配置调整进行充分的压力测试。