常见问题
是否可以多线程或多进程执行作业?
有三种方法可以解决这个问题——但是我们建议谨慎分析此类需求(真的有必要吗?)。
-
向步骤添加
TaskExecutor
。用于配置步骤的`StepBuilder` 提供了一个可以设置的“taskExecutor”属性。只要步骤本身是可重启的(实际上是幂等的),这就可以工作。并行作业示例展示了它在实践中的工作方式——这使用了“进程指示器”模式在业务事务内将输入记录标记为已完成。 -
使用
PartitionStep
将步骤执行明确地拆分成多个步骤实例。Spring Batch 有一个本地多线程实现的此主要策略 (PartitionHandler
),这使其成为 IO 密集型作业的绝佳选择。请记住,对于以这种方式执行的步骤中的有状态组件,请使用scope="step"
,以便为每个步骤执行创建单独的实例,并且线程之间没有串扰。 -
使用
spring-batch-integration
模块中实现的远程分块方法。这需要一些持久性中间件(例如 JMS)才能在驱动步骤和远程工作器之间进行可靠的通信。基本思想是在驱动进程上使用特殊的ItemWriter
,并在工作进程上使用监听器模式(通过ChunkProcessor
)。
如何使项目读取器线程安全?
您可以同步read()
方法(例如,通过将其包装在一个执行同步的委托器中)。请记住,您将失去可重启性,因此最佳实践是将步骤标记为不可重启,并且为了安全(和高效),您还可以将读取器的saveState=false
。
Spring Batch 对使用灵活策略和默认实现的理念是什么?您可以为此或那个属性添加一个公共 getter 吗?
Spring Batch 中有许多扩展点供框架开发人员(而不是业务逻辑的实现者)使用。我们期望客户端创建他们自己更具体的策略,这些策略可以插入以控制诸如提交间隔(CompletionPolicy
)、处理异常的规则(ExceptionHandler
)等等。
通常,我们试图劝阻用户扩展框架类。Java 语言并没有给我们足够的灵活性来将类和接口标记为内部的。通常,您可以预期源树顶层的`org.springframework.batch.*` 包中的任何内容都是公共的,但不一定是可子类的。我们不鼓励扩展大多数策略的具体实现,而是采用组合或派生方法。如果您的代码只能使用 Spring Batch 中的接口,则可以获得最大的可移植性。
Spring Batch 与 Quartz 有什么区别?它们两者在解决方案中是否有位置?
Spring Batch 和 Quartz 的目标不同。Spring Batch 提供处理大量数据的功能,而 Quartz 提供调度任务的功能。因此,Quartz 可以补充 Spring Batch,但并非互斥技术。常见的组合是使用 Quartz 作为 Spring Batch 作业的触发器,使用 Cron 表达式和 Spring Core 方便的SchedulerFactoryBean
。
如何使用 Spring Batch 调度作业?
使用调度工具。有很多这样的工具。示例:Quartz、Control-M、Autosys。Quartz 没有 Control-M 或 Autosys 的所有功能——它应该轻量级。如果您想要更轻量级的工具,您可以只使用操作系统(cron
、at
等)。
简单的顺序依赖关系可以使用 Spring Batch 的作业步骤模型和 Spring Batch 中的非顺序功能来实现,我们认为这是相当常见的。实际上,它更容易纠正调度程序的常见误用——配置数百个作业,其中许多作业不是独立的,而只是依赖于另一个作业。
Spring Batch 如何允许项目通过并行处理或其他方式优化性能和可扩展性?
我们认为这是Job
或Step
的角色之一。Step
的具体实现解决了将业务逻辑分解并高效地在并行进程或处理器之间共享的问题(参见PartitionStep
)。这里有很多技术可以发挥作用。其本质只是一组对分布式代理的并发远程调用,这些代理可以处理一些业务处理。由于业务处理通常已经模块化——例如,输入一个项目,处理它——Spring Batch 可以通过多种方式来制定分发策略。我们有一些经验的一种实现是一组处理业务处理的远程 Web 服务。我们将特定范围的主键发送到多个远程调用的输入中。同样的基本策略可以与任何 Spring Remoting 协议(普通 RMI、HttpInvoker、JMS、Hessian 等)一起使用,只需在执行层配置中更改几行代码。
如何使用消息传递来扩展批处理架构?
现有项目的大量实践证明,采用流水线方法进行批处理非常有利,从而提高了弹性和吞吐量。我们经常面临关键任务应用程序,其中审计跟踪至关重要,需要保证处理,但同时对负载下的性能有极其严格的限制,或者高吞吐量具有竞争优势。
Matt Welsh 的研究表明,分阶段事件驱动架构 (SEDA) 比更严格的处理架构具有巨大的优势,而面向消息的中间件 (JMS、AQ、MQ、Tibco 等) 为我们提供了很多现成的弹性。在系统中,下游和上游阶段之间存在反馈,因此可以调整消费者的数量以适应需求量,这尤其有利。那么这如何融入 Spring Batch?spring-batch-integration 项目在 Spring Integration 中实现了这种模式,可用于扩展对许多待处理项目的远程处理。特别是请参见“chunk”包以及其中的ItemWriter
和ChunkHandler
实现。