• 几天前在生产上遇到了一个job失败,重启后csv文件不可写的问题.当时认为是batch的重启机制导致的.后来经过分析后是因为1.batch用了集群环境2.重启机制两方面导致的;
  • 前情提要:job中的一个step处于FAILED状态,step是一个chunk写成的,包括reader,processor,writer( FlatFileItemWriter )三部分,其中processor抛出了异常,导致step失败;
  • batch系统在运行时会将失败时step的状态保存到 batch_step_execution_context 在这里插入图片描述
{"map":[{"entry":[
{"string":"FlatFileItemWriter.current.count","long":228},
{"string":"FlatFileItemWriter.written","long":0},
{"string":["batch.taskletType","org.springframework.batch.core.step.item.ChunkOrientedTasklet"]},
{"string":"selectBdBizOver.read.count","int":0},
{"string":["batch.stepType","org.springframework.batch.core.step.tasklet.TaskletStep"]}
 

该表保存了step运行退出时的状态 (成功的话不会保存),step_execution表示该step的唯一标识,short_context表示执行上下文,会在step重启时用于恢复; 其中FlatFileItemWriter.current.count为上一次退出时csv文件总共写入了多少字节,step恢复时会从该位置进行恢复;FlatFileItemWriter.written表示csv内的内容写了多少(除去表头的内容)

  • 回到正题,出现File is not writable的异常是在batch自带的一个文件工具类中在这里插入图片描述

该工具类中一个很重要的参数是 restarted 决定着是否重新生成一个csv文件,当一个step处于FAILED状态并且FlatFileItemWriter中的属性shouldDEleteIfEmpty为false时,该值为true,意味着不会重新生成文件,而且会直接走到54行 if(!file.canWrite())进行判断该路径是否可达可写,在此时出现了问题.

因为在生产上使用的集群环境,job第一次开始时是在第一台服务器上,那时已经生成好了包含表头的csv文件.而在重启时job是在第二台服务器上运行的.
又因为job的重启机制(restarted为true)导致该step不会重新生成csv文件,而是直接检查文件路径是否可写,发现文件并不存在,于是抛出了异常

  • 如果是在同一台服务器上重启则不会出现该问题
  • shouldDeleteIfEmpty属性设为true,系统会在恢复时检查该属性,如果为true且上文batch_step_execution_context表中的short_contextFlatFileItemWriter.written0(说明csv文件内容为空)就会将restarted属性设为false fileUtils会重新生成一份csv文件(FlatFileItemWriter的359行会在初始化写入缓存时调用fileUtils.setOutputFile(...)方法,如下图所示).
  • 该解决存在缺陷,如果csv文件内容不为空的话,restarted属性还是为true
问题摘要几天前在生产上遇到了一个job失败,重启后csv文件不可写的问题.当时认为是batch的重启机制导致的.后来经过分析后是因为1.batch用了集群环境2.重启机制两方面导致的;问题分析前情提要:job中的一个step处于FAILED状态,step是一个chunk写成的,包括reader,processor,writer(FlatFileItemWriter)三部分,其中proc... 1.对于chunk类型的Step,spring batch为我们提供了用于管理它的状态 2.状态的管理是通过ItemStream接口来实现的 3.ItemStream接口: (1)open():每一次step执行会调用 (2)Update():每一个chunk去执行都会调用 (3)Close():所有的chunk执行完毕会调用 ![file](https://imgconv...
文章目录一、自定义CustomItemReader二、job 监听器三、配置job四、改造CustomItemReader,发生异常批处理作业从停止的地方重新启动 前言:在一些业务场景中,可能现有的reader不符合我们的要求,SpringBatch提供自定义reader,实现ItemReader接口,满足我们业务场景。 SpringBatch其它文章直通车: SpringBatch读单个文...
欢迎使用Spring Batch示例。Spring Batch是一个用于执行批处理作业的弹簧框架模块。我们可以使用spring批处理来处理一系列作业。 目录[隐藏] 1Spring Batch示例 1.1Spring Batch示例 1.2Spring批处理示例目录结构 1.3Spring Batch Maven依赖项 这次这个坑是我们用bochs下的bximage创建磁盘的时候: $ bximage ========================================================================
'node' is not recognized as an internal or external command, operable program or batch file.