易君召
易君召
发布于 2026-07-14 / 16 阅读
0
0

Apache Camel SFTP 大文件分片传输技术选型

一、原生组件能力(camel-ftp /mina-sftp)

1. 原生不支持云端分片上传协议(如 S3 multipart)

标准 SFTP 协议本身没有统一的 “分片上传接口”,Camel SFTP 生产者没有内置一键分片上传 API,无法像对象存储那样直接分块并行上传同一文件到远端并自动合并。

2. 原生支持「流式读写 + 断点续传下载」(单文件流,非分片)

  • 下载大文件:开启 streamDownload=true,文件以 InputStream 流式拉取,不载入全量内存;搭配 localWorkDirectory + binary=true 支持断点续传(中断后从已下载字节偏移续下)Apache Cam...。

  • 上传大文件:仅支持单流完整写入,默认一次性把文件流推送远端;一旦中断必须从头重传,原生无上传断点续传

  • 局限:超大文件(几十 GB)上传容易超时、占连接时长、失败全重传,无并行提速。

3. Camel 4.8+ Chunking DSL 只是本地切分,不是远端分片

新的 .chunking() 仅在本地路由内把输入流切成小块,每块单独发一条消息;但发给 SFTP 时,每一块会变成独立小文件上传到远端,不会自动合并成原文件,需要自己写合并逻辑Apache Cam...。

二、三种落地分片同步方案(按推荐优先级)

方案 1:本地预分片 + SFTP 分批上传 + 远端合并(最稳定,生产常用)

流程

  1. Processor 拆分本地大文件为固定 size 分片(128M/256M),命名 xxx.001.partxxx.002.part

  2. 循环把所有分片顺序 / 并行上传 SFTP 临时目录;

  3. 全部分片上传完成后,发一条 “合并指令”;

  4. 远端脚本(shell/python)检测分片齐全,cat *.part > full.file,校验 MD5 后删除分片;

  5. 本地记录分片上传进度(Redis / 数据库)实现断点续传,断了只传缺失分片。

Camel 路由伪代码(Java DSL)

from("file:/source/bigfiles")
    .process(new SplitBigFileProcessor(256 * 1024 * 1024)) // 本地切256M分片
    .split(body()) // 每个分片单独消息
        .parallelProcessing() // 并行上传提速
        .to("sftp://user@server/tmp/chunks?password=xxx&binary=true")
    .end()
    .bean(MarkUploadComplete.class) // 标记分片全部上传完成
    .to("sftp://user@server/tmp?fileName=merge.trigger"); // 触发远端合并

优点:兼容所有 SFTP 服务端、可控并发、断点续传只重传失败分片、内存友好; 缺点:需要远端执行合并脚本,跨端协同。

方案 2:Camel Chunking DSL 本地流分片上传(无需落地临时分片文件)

Camel 4.8 及以上可用,不生成本地物理分片,内存流式切块

from("file:/source/bigfiles")
    .chunking(256_000_000) // 流切成256MB内存块
    .split(body())
        .parallelProcessing()
        .setHeader(CamelFileName, simple("${file:name}.${exchangeProperty.chunkIndex}.part"))
        .to("sftp://user@server/tmp/chunks?password=xxx&binary=true")
    .end()
    .to("sftp://user@server/tmp/merge.flag");
  • 优势:无本地分片磁盘 IO;

  • 短板:依然需要远端合并;流分片失败会丢失整块,断点续传实现更复杂。

方案 3:封装 JSch/Mina-SSHD 底层 API 实现「单文件追加分片」(无远端脚本)

SFTP 底层支持 open(APPEND) 模式:

  1. 首次上传创建空目标文件;

  2. 后续分片通过 SFTP 追加写入同一文件;

  3. 本地记录已上传字节偏移,中断后从偏移处追加,实现上传断点续传

需要自定义 Processor 封装 JSch ChannelSftp,Camel 原生 SFTP Producer 不暴露 append 分片接口。 适合无法在 SFTP 服务器执行脚本、要求远端自动合并的场景。

三、配套大文件优化配置(不分片也能缓解内存 / 超时)

SFTP 生产者大文件上传基础优化

sftp://user@host/path?
binary=true
&streamUpload=true
&soTimeout=300000
&sendBufferSize=1048576
  • streamUpload=true:流式上传,不把文件全读入内存;

  • sendBufferSize:增大发送缓冲区;

  • soTimeout:延长 socket 超时,适配超大文件长时间传输。

下载断点续传配置

sftp://user@host/path?
binary=true
&streamDownload=true
&localWorkDirectory=/tmp/sftp-work

localWorkDirectory 本地缓存已下载片段,中断续下。

四、关键对比总结

特性

Camel 原生 SFTP

本地预分片方案

底层 append 自定义分片

远端自动合并

❌(需远端脚本)

✅(单文件追加)

上传断点续传

❌(全量重传)

✅(分片粒度续传)

✅(字节偏移续传)

并行提速

❌单流

✅多分片并行

❌单文件追加串行

兼容所有 SFTP 服务

开发成本

高(底层 API 封装)

五、最终建议

  1. 常规生产同步(GB 级文件):选用「本地预分片 + 并行上传 + 远端 shell 合并」,开发成本适中、稳定性最好;

  2. 禁止服务端执行脚本:自定义 JSch 追加分片 Processor,实现单文件断点续传上传;

  3. 文件 < 5GB、网络稳定:直接用原生 SFTP 流式上传,无需分片;

  4. 同步完成后务必增加两端 MD5 校验,防止分片传输损坏。


原文链接 https://www.yijunzhao.cn/archives/apache-camel-sftp-large-file-sharding-transfer-comparison

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/


评论