Spring batch的org.springframework.batch.item.ItemStreamException: File is not writable:异常

问题摘要

  • 几天前在生产上遇到了一个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

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

b0b0大魔王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值