公司准备换用spring batch批处理框架,简单的看了下框架的实现。记录下自己对这个框架的了解和认识。它的用途主要用于
1 从数据库文件或队列中读取大量的数据
2 以某种方式 ,步骤 按照一定的顺序处理数据
3 将大量传进来的数据修改后保存
spring batch大致架构图 如图:
基本组件
Job
用于存储Job的容器。
JobInstance
Job的运行实例,Job每执行一次都会涉及到一个JobInstance。jobInstance=JobName+JobParameters
JobExecution
用于存储Job的运行记录。
JobParameters
用于Job运行时的参数。
JobRepository
持久化job元数据
ExecutionContext
用于保存job/step运行时需要持久化的状态信息。
Step
一个Job可以分为多个Step。
Tasklet
tasklet是任务的具体执行逻辑,可以自定义一个完整的tasklet.
Chunk
块处理,可以通过控制提交间隔或者提交一个完成策略(两者只能设其一)来控制块的大小。
JobExecution和JobInstance概念有点像,对于每执行同一个Job的时候都会产生JobInstance和JobExecution,但是会出现执行失败和成功的情况,重跑这个Job还是会生成一个JobExecution,但是JobInstance只有一个。
分析启动流程
至于怎么用官方文档已经写的很清晰了,我们来看看其中的具体实现。
首先spring batch会提供一个JobLauncher的接口用来执行Job.
它的默认实现是SimpleJobLauncher,我们来看看它的代码
public JobExecution run(final Job job, final JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
JobParametersInvalidException {
Assert.notNull(job, "The Job must not be null.");
Assert.notNull(jobParameters, "The JobParameters must not be null.");
……
可以看到job和JobParameters不能为空。
final JobExecution jobExecution;
JobExecution lastExecution = jobRepository.getLastJobExecution(job.getName(), jobParameters);
if (lastExecution != null) {
if (!job.isRestartable()) {
throw new JobRestartException("JobInstance already exists and is not restartable");
}
/*
* validate here if it has stepExecutions that are UNKNOWN, STARTING, STARTED and STOPPING
* retrieve the previous execution and check
*/
for (StepExecution execution : lastExecution.getStepExecutions()) {
BatchStatus status = execution.getStatus();
if (status.isRunning() || status == BatchStatus.STOPPING) {
throw new JobExecutionAlreadyRunningException("A job execution for this job is already running: "
+ lastExecution);
} else if (status == BatchStatus.UNKNOWN) {
throw new JobRestartException(
"Cannot restart step [" + execution.getStepName() + "] from UNKNOWN status. "
+ "The last execution ended with a failure that could not be rolled back, "
+ "so it may be dangerous to proceed. Manual intervention is probably necessary.");
}
}
}
通过从JobRepository中获取最后一个Job运行的记录(JobExecution ),检验存在的job是否支持重启,job中的step是否已经在运行。相应的抛出其对应的异常。
job.getJobParametersValidator().validate(jobParameters);
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
这里提供检验器来检验job启动的参数,它默认提供一个DefaultJobParametersValidator来实现验证job启动参数,框架提供一个CompositeJobParametersValidator类,这个类可以设置一组检验job参数的校验器,我们可以自定义一堆检验器利用CompositeJobParametersValidator来遍历校验。
校验完创建一个Job记录。(其中细节之后再记录,本篇先记录启动方法)
这里默认通过spring提供的一个AsyncTaskExecutor异步去执行这个job。
catch (TaskRejectedException e) {
jobExecution.upgradeStatus(BatchStatus.FAILED);
if (jobExecution.getExitStatus().equals(ExitStatus.UNKNOWN)) {
jobExecution.setExitStatus(ExitStatus.FAILED.addExitDescription(e));
}
jobRepository.update(jobExecution);
}
这里捕捉到TaskRejectedException更新下jobExecution的状态。