Axon Framework - saga 基础设施

Axon Framework - saga 基础设施,第1张

事件需要重定向到适当的 saga 实例。 为此,需要一些基础设施类。 最重要的组件是SagaManager 和 SagaRepository 。

与处理事件的任何组件一样,处理是由事件处理器完成的。 但是,sagas 不是处理事件的单例实例。 他们有各自的生命周期,需要加以管理。

Axon 通过AnnotatedSagaManager 支持生命周期管理,它被提供给事件处理器以执行处理程序的实际调用。 它使用要管理的 saga 的类型以及可以存储和检索该类型的 saga 的 SagaRepository 进行初始化。 单个 AnnotatedSagaManager 只能管理单个 saga 类型。

使用配置 API 时,Axon 将为大多数组件使用合理的默认值。 但是,强烈建议定义一个SagaStore 实现来使用。 SagaStore 是在某处“物理”存储 saga 实例的机制。 AnnotatedSagaRepository (默认)使用 SagaStore 来存储和检索需要的 Saga 实例。

Axon Configuration API

Spring Boot AutoConfiguration

SagaRepository 负责存储和检索 saga,供 SagaManager 使用。 它能够通过它们的标识符以及它们的关联值来检索特定的 saga 实例。

但是,有一些特殊要求。 由于 saga 中的并发处理是一个非常微妙的过程,repository 必须确保对于每个概念 saga 实例(具有相同的标识符)在 JVM 中仅存在一个实例。

Axon 提供AnnotatedSagaRepository 实现,它允许查找 saga 实例,同时保证只能同时访问 saga 的单个实例。 它使用 SagaStore 来执行 saga 实例的实际持久化。

使用的实现选择主要取决于应用程序使用的存储引擎。 Axon 提供了JdbcSagaStore 、 InMemorySagaStore 、 JpaSagaStore 和 MongoSagaStore 。

在某些情况下,应用程序受益于缓存 saga 实例。 在这种情况下,有一个CachingSagaStore 包装了另一个实现以添加缓存行为。 请注意, CachingSagaStore 是直写式缓存,这意味着保存 *** 作始终会立即转发到后备存储,以确保数据安全。

JpaSagaStore 使用 JPA 来存储 sagas 的状态和关联值。 Sagas 本身不需要任何 JPA 注解; Axon 将使用 Serializer 对 sagas 进行序列化(类似于事件序列化,您可以在 XStreamSerializer 或 JacksonSerializer 之间进行选择,可以通过在应用程序中配置默认的 Serializer 来设置。有关更多详细信息,请参阅序列化程序 .

JpaSagaStore 配置有 EntityManagerProvider ,它提供对要使用的 EntityManager 实例的访问。 这种抽象允许使用应用程序管理和容器管理的 EntityManager 。 或者,您可以定义序列化程序来序列化 Saga 实例。 Axon 默认为 XStreamSerializer 。

JdbcSagaStore 使用纯 JDBC 来存储阶段实例及其关联值。 与 JpaSagaStore 类似,saga 实例不需要知道它们是如何存储的。 存储使用序列化程序序列化 saga 实例。

您应该使用DataSource 或 ConnectionProvider 配置 JdbcSagaStore 。 虽然不是必需的,但在使用 ConnectionProvider 进行初始化时,建议将实现包装在 UnitOfWorkAwareConnectionProviderWrapper 中。 它将检查当前工作单元中是否存在已打开的数据库连接,以确保工作单元内的所有活动都在单个连接上完成。

与 JPA 不同, JdbcSagaRepository 使用纯 SQL 语句来存储和检索信息。 这种方法可能意味着某些 *** 作依赖于特定于数据库的 SQL 方言。 也可能是某些数据库供应商提供了您想使用的非标准功能。 为此,您可以提供自己的 SagaSqlSchema 。 SagaSqlSchema 是一个接口,它定义了存储库需要在底层数据库上执行的所有 *** 作。 它允许您自定义为每个 *** 作执行的 SQL 语句。 默认值为 GenericSagaSqlSchema 。 其他可用的实现是 PostgresSagaSqlSchema 、 Oracle11SagaSqlSchema 和 HsqlSagaSchema 。

Schema 构建

请注意,Axon 不会为您创建开箱即用的数据库 schema 。 例如,在使用 Spring Boot 时也不行。

要构建 schema,应该调用JdbcSagaStore#createSchema 。 默认情况下,这将使用 GenericSagaSqlSchema 。 您可以通过 JdbcSagaStore.Builder 配置不同的版本来更改 schema。

MongoSagaStore 将 saga 实例及其关联存储在 MongoDB 数据库中。 MongoSagaStore 将所有 saga 存储在 MongoDB 数据库中的单个集合中。 对于每个 saga 实例,都会创建一个文档。

MongoSagaStore 还确保在任何时候,对于单个 JVM 中的任何唯一 Saga,都只存在一个 Saga 实例。 这可确保不会因并发问题而丢失状态更改。

MongoSagaStore 使用 MongoTemplate 和可选的 Serializer 初始化。 MongoTemplate 提供了对存储 sagas 的集合的引用。Axon 提供了 DefaultMongoTemplate ,它接受一个 MongoClient 实例以及数据库名称和存储 sagas 的集合名称。数据库名称 和集合名称可以省略。 在这种情况下,它们分别默认为 “axonframework” 和 “sagas” 。

如果使用数据库支持的 saga 存储,保存和加载 saga 实例可能是一项相对昂贵的 *** 作。 在短时间内多次调用同一个 saga 实例的情况下,缓存可能对应用程序的性能特别有益。

Axon 提供CachingSagaStore 实现。 它是一个包装了另一个 SagaStore 的 SagaStore ,它负责实际存储。 加载 saga 或关联值时, CachingSagaStore 将首先查询其缓存,然后再委托给包装的 repository。 存储信息时,所有调用总是被委派以确保后备存储始终对 saga 的状态有一致的视图。

要配置缓存,只需将任何SagaStore 包装在 CachingSagaStore 中。 CachingSagaStore 的构造函数采用三个参数: 1. 要包装的 SagaStore 2. 用于关联值的缓存 3. 用于 saga 实例的缓存

后两个参数可能指的是同一个缓存,也可能指不同的缓存。 这取决于您的特定应用程序的要求。

需要提供正常业务逻辑接口和回退接口。只能嵌套2层,顶级saga是一层,子服务是第二层。

saga讲述的是如何处理长活事务。一个系统中如果流程很长,如果需要保证数据库ACID特性,则事务时间很长,这样容易出现死锁错误。对系统进行分布式拆分,形成多个子系统(子事务)。由一个协调者统一管理,最终统一的提交/回滚,则可以避免事务时间过长的问题(需要注意的是,这里的提交和回滚是业务逻辑层面的,而非数据库)。

Saga模型起源于1987年,是分布式事务相关概念最早出现的。Saga模型是把一个分布式事务拆分为多个本地事务,每个本地事务都有相应的执行模块和补偿模块(对应TCC中的Confirm和Cancel),当Saga事务中任意一个本地事务出错时,可以通过调用相关的补偿方法恢复之前的事务,达到事务最终一致性。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9388142.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存