Frequently Asked Questions

Is it possible to execute jobs in multiple threads or multiple processes?

有三种方法可以解决这一点——但我们建议在分析此类要求时保持谨慎(真的有必要吗?)。

  • TaskExecutor 添加到步骤中。配置步骤提供的 StepBuilder 具有可以设置的“taskExecutor”属性。只要步骤在本质上可重新启动(有效地幂等),这就会奏效。平行作业示例展示了它如何在实践中工作 - 它使用“过程指示器”模式来标记业务事务中的输入记录为已完成。

  • 使用 PartitionStep 明确地在多个步骤实例之间拆分步骤执行。Spring Batch 针对此主策略提供了本地多线程实现 (PartitionHandler),这使其成为对 IO 密集型作业的绝佳选择。请记住,对使用这种方式执行的步骤中的有状态组件使用 scope="step",以便为每个步骤执行创建单独的实例,并且线程之间不存在交叉对话。

  • 使用 spring-batch-integration 模块中实现的远程分块方法。这需要一些持久中间件(例如 JMS)来实现驱动步骤和远程工作器之间的可靠通信。基本思想是在驱动过程中使用特殊的 ItemWriter,并在工作器进程上使用侦听器模式(通过 ChunkProcessor)。

How can I make an item reader thread safe?

您可以同步“read()”方法(例如,通过将其包装在执行同步的委托程序中)。请记住,您会失去可重新启动性,因此最佳实践是将该步骤标记为不可重新启动,为了安全(且高效),您还可以对读取器设置“saveState=false”。

What is the Spring Batch philosophy on the use of flexible strategies and default implementations? Can you add a public getter for this or that property?

对于框架开发者(相对于业务逻辑的实现者)而言,Spring 批处理中有许多扩展点。我们期待客户端创建自己的特定策略,以将这些策略插入以控制提交间隔(CompletionPolicy)、如何处理异常的规则(ExceptionHandler)以及许多其他策略。

通常情况下,我们会劝阻用户扩展框架类。Java 语言没有给我们标记类和接口为内部的灵活性。通常而言,你可以期望源树顶级结构的如下包中的任何内容为公开内容,但并不一定具有子类:org.springframework.batch.*。不鼓励扩展我们对大多数策略的具体实现,而更鼓励使用组合或分支方法。如果你的代码只使用 Spring 批处理中的这些接口,那将会为你带来最大的可移植性。

How does Spring Batch differ from Quartz? Is there a place for them both in a solution?

Spring 批处理和 Quartz 有不同的目标。Spring 批处理提供处理大量数据的功能,而 Quartz 提供任务计划功能。所以 Quartz 可以补充 Spring 批处理,但它们并不是排斥的技术。一种常见的组合方式是使用 Quartz,以此来作为使用 Cron 表达式和 Spring Core 便利工具 SchedulerFactoryBean 的 Spring 批处理作业的触发器。

How do I schedule a job with Spring Batch?

使用计划工具。有很多这样的工具。例如:Quartz、Control-M、Autosys。Quartz 没有 Control-M 或 Autosys 的所有功能 - 它应该是轻量级的。如果你想要更轻量级的东西,你可以使用操作系统(cronat 等)。

可以使用 Spring 批处理的作业步骤模型和 Spring 批处理中的非顺序特性来实现简单的顺序相关项。我们认为这种方法很常见。实际上,它可以帮助我们更轻松地纠正计划程序常见的错误使用方式 - 配置成百上千个作业,其中许多作业之间并非独立,而只是相互依赖。

How does Spring Batch allow project to optimize for performance and scalability (through parallel processing or other)?

我们将其视为 JobStep 的作用之一。Step 的特定实现方式处理业务逻辑的分解以及在并行进程或处理器之间高效地共享此逻辑的问题(参见 PartitionStep)。这里有许多技术可以发挥作用。其实质上只是一组并发远程调用,这些调用会处理某些业务处理,并可以将其分发到分布式代理。由于业务处理通常已经是模块化的(例如输入一个项目并对其进行处理),Spring 批处理可以用多种方式制定分布策略。我们使用过的一种实现方案是一组处理业务处理的远程 Web 服务。我们将数字主键范围发送给每个远程调用的输入。在执行层配置中,同样的基本策略适用于任何 Spring 远程通信协议(普通的 RMI、HttpInvoker、JMS、Hessian 等),修改几行即可。

How can messaging be used to scale batch architectures?

许多现有项目实践证明,流水线式批处理方法极有帮助,它会导致更高的恢复能力和吞吐量。我们经常面临任务攸关的应用,需要审计跟踪,还需要保证处理,但此类应用在负载下的性能限制极高,或者高吞吐量具有竞争优势。

Matt Welsh 的研究表明,分阶段事件驱动架构 (SEDA) 比更严格的处理架构具有极大的优势,消息导向中间件(JMS、AQ、MQ、Tibco 等)提供了许多现成可用且极具恢复能力的功能。在向下游和上游阶段之间存在反馈的系统中具有特定的好处,因此可以调整使用者的数量来考虑到需求量。那么这如何融入 Spring 批处理中呢?spring-batch-integration 项目在 Spring Integration 中实现了此模式,并且可以用来放大远程处理任何拥有多个要处理的项目的步骤。尤其请参阅“块”包,以及其中的 ItemWriterChunkHandler 实现。