Camel从2.22.1升级到3.9.0后SFTP路由出现文件删除、目录切换报错问题
问题根因
你遇到的报错是Camel 3.x版本SFTP组件的核心逻辑变更和现有配置冲突导致的,具体原因如下:
disconnect=true参数的处理逻辑在Camel 3.x中发生了变更:2.x版本中该参数会在整批文件处理完成后断开连接,3.x版本调整为每处理完单个文件就主动断开SFTP连接,但后续删除.process文件、切换目录回轮询根路径的操作还需要使用原有连接,连接提前关闭就会触发Pipe closed、目录切换失败、文件不存在的报错。- preMove与delete操作的事务边界调整:Camel 3.x优化了文件操作的校验逻辑,preMove重命名文件后,连接断开再重连时,SFTP上下文的当前工作目录没有同步更新,即便文件实际存在,组件按旧路径寻址也会抛出不存在的异常。
stepwise=false没有解决根问题反而导致性能下降:关闭stepwise模式后,Camel不再采用逐层切换目录的方式操作文件,每次操作都要携带全路径向SFTP服务器发起请求,批量处理50个文件时会产生大量冗余请求,自然会导致运行速度极慢,同时也解决不了连接提前断开的核心问题,所以报错依然存在。
可落地的解决方案
按优先级从高到低选择即可:
- 调整断开连接的时机
将原有配置中的disconnect=true替换为disconnectOnBatchComplete=true,该参数会在你配置的maxMessagesPerPoll=50整批文件全部处理完成后再断开连接,既满足连接释放的需求,也不会打断单批文件的操作流程,修改后的路由配置参考:
from(sftp://" + sourceUrl + "&preferredAuthentications=password&includeExt=xml&delete=true&disconnectOnBatchComplete=true&maxMessagesPerPoll=50&preMove=${file:name.noext}.process")
- 补充异常场景的兜底配置
额外增加moveFailed=${file:name.noext}.failed参数,处理失败的文件会自动重命名为.failed后缀,避免残留的.process文件干扰下一次轮询,同时可增加synchronous=true参数让文件操作全在同一线程执行,避免异步上下文丢失导致的路径识别问题。 - 特殊场景适配方案
如果你的业务要求必须处理完单个文件就断开连接,就删除disconnect=true配置,新增consumer.bridgeErrorHandler=true,在路由末尾手动调用SFTP API执行文件删除操作,自行控制删除逻辑在连接断开前完成。
内容的提问来源于stack exchange,提问作者D007
相关产品推荐
相关产品推荐

