如何为 Spring Batch 应用反应式

kon*_* zu 2 java spring reactive

我想知道如何将 Spring React 应用于 Spring Batch。我该怎么做?为什么我们要把 Spring Reactive 应用于 Spring Security?为什么我可以应用到Spring Security,但不能应用Reactive到Spring Batch。

小智 5

Spring Batch 的响应式版本不存在。Spring 开发人员正在此Github 问题中讨论此实现。

我想标记以下评论,它解释了所有原因。

Spring Batch 和反应流

首先,Reactive Streams 是为数据流(无限)设计的,而 Spring Batch 是为固定数据集(有限)设计的批处理框架。在我看来,这已经是一个根本性的不匹配,可能导致这两个工具之间的非自然集成。

现在,即使我们尝试在 Spring Batch 中以某种方式引入“响应式”,我们也需要小心一些设计选择。以下Spring 框架常见问题解答部分的摘录是关键:

For handlers to be fully non-blocking, you need to use reactive libraries throughout the processing chain,
all the way to the persistence layer.
Run Code Online (Sandbox Code Playgroud)

如果堆栈是部分响应式的,Spring 框架甚至建议继续使用阻塞模型:

By all means, keep using Spring MVC if you are developing web apps that don't benefit from a non-blocking
programming model, or that use blocking JPA or JDBC APIs for persistence (typically in combination with
thread-bound transactions).
Run Code Online (Sandbox Code Playgroud)

根据这些陈述,要使 Web 应用程序完全响应式,整个堆栈都应该是响应式的,从控制器一直到持久层。这对于批处理应用程序没有什么不同,只是我们这里显然没有控制器,但端到端作业执行应该是反应性的。拥有与阻塞作业存储库交互的“反应式非阻塞步骤”是没有意义的。

因此,要真正从这个响应式故事中受益,整个框架应该是响应式的,从批处理工件(读取器、处理器、写入器、侦听器等)到基础设施 bean(作业存储库、事务管理器等)。为了实现这一目标,需要付出巨大的努力:

  • 应提供反应式作业存储库实现
  • 所有使用的 API PlatformTransactionManager(即BatchConfigurerTaskletStepBuilderHelper等)都应更新为使用新引入的org.springframework.transaction.TransactionManager接口。这是为了能够根据需要提供一个ReactiveTransactionManager或一个经典。PlatformTransactionManager
  • 应更新读取器/写入器的所有实现以使用非阻塞 API(文件 IO、数据库 IO 等)
  • 还有许多其他变化

而且,当前面向块的处理模型实际上与反应式范式不兼容。原因是在ChunkOrientedTasklet读取下一个块之前等待 chunkProcessor(处理器 + 写入器)处理整个块:

For handlers to be fully non-blocking, you need to use reactive libraries throughout the processing chain,
all the way to the persistence layer.
Run Code Online (Sandbox Code Playgroud)

因此,这个实现也应该进行调整。所有这些更改都是必需的,甚至无需讨论 Spring Batch 当前的并发模型(与反应式范例不兼容)和作业存储库级别使用的乐观锁定策略。

在我看来,“反应式支持”不是我们可以在 Spring Batch 中引入的功能,它实际上需要完全重写框架的 80%(如果不是更多)。出于所有这些原因,我认为这种集成的成本/收益太高而无法考虑,但我愿意相信其他情况。