FTP下载大文件后命令无法正常退出

下载数据库备份200G遇到的问题

前端时间在DevOps平台的开发中遇到了需要下载200G超大数据库备份文件的需求:不论是在java程序里面还是FTP的命令行脚本里面都遇到了文件下载完成后,当前代码不能退出的问题。纠结与测试良久发现这是FTP多端口通信导致的问题。

什么是FTP主被动模式

首先简单理解一下什么是FTP主被动模式:默认情况下FTP协议使用21端口通信,但这是控制端口,只用来传输命令,主动模式下,FTP启用20端口(可以配置,不是必须20)连接客户端的随机端口传输真正的数据,如果在公网上或者长距离VPN,服务器主动模式----受到NAT等影响,往往不能穿透防火墙等,因此我们一般使用被动模式。被动模式下,服务器主动开启一个数据端口,被动等待客户端的连接,因为客户端始终主动发起连接请求,所以不受NAT等影响,能穿透防火墙。

为什么文件传输完后,命令不能退出

因为FTP的多端口通信,数据文件只在数据端口传输,假设数据文件很大需要传输一整天才能完成,那么数据端口在这个一整天都很忙碌,而到控制端口的网络连接则一直空闲。我们知道长距离网络会间隔很多路由器,有很多都不能一直保持网络连接,当某一条链路很久没有数据传输,那么这个链路会被这些中间网络设备断掉。等真正的数据传输完成,客户端打算通过控制端口告诉服务器,文件下载完毕,却发现控制端口的链路已经不能使用,所以程序出现异常(有些客户端挂起,有些抛出异常)。

怎么解决

保持网络连接的活性,心跳包是惯用手法,如果是大家使用Apache的commons-net包中的java FTP客户端,其中已经预制了保持控制端口心跳的功能:

// 设置控制端口的响应超时
this.ftpClient.setControlKeepAliveReplyTimeout(5000);
// 重要,每隔15S向控制端口发送心跳数据,保证控制端口的活性
this.ftpClient.setControlKeepAliveTimeout(15);

有了这2行代码,我发现下载200G,300G文件,无论是下载了一天还是1天半,程序都能正常工作。
当然如果使用了其他客户端,没有提供对应的心跳函数,则需要自己在下载数据之前新建一个线程,在这个线程不停的向控制端口发送空指令(NoOp指令)。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值