为什么Java FTP客户端的传输速率存在很大差异

时间:2013-01-17 16:08:40

标签: java apache ftp

也许有人可以回答我这个问题。在我最近的工作中,我注意到我的应用程序(通过FTP下载更新)在与Linux一起使用时非常慢。我在Mac上开发这些东西,所以我之前没有注意到这个问题,因为Mac OS下的下载速度并不是很低。但是当转向Linux时,应用程序表现得非常不同。

FTP服务器(在Ubuntu服务器上运行的纯FTP)连接到与客户端相同的LAN,因此不考虑Internet速度问题。由于性能低下,我将Apache FTPClient更改为edtFTPj / Free。差异仍然显着但可以接受。作为测试用例,我总是下载大小约为30 MB的文件。然后我检查了ftp服务器日志以了解传输速率。

亲眼看看。提到的VMWare在Mac上运行。除非另有说明,否则Java是Oracle Java 1.7。

Apache Commons Net 2.3

代码看起来像这样

  FTPClient ftp = new FTPClient();
  ftp.connect("srv0006");
  ftp.login("anonymous", "asd");
  ftp.setFileType(FTP.BINARY_FILE_TYPE);
  File target = new File("/tmp/pub.tar");
  FileOutputStream fos = new FileOutputStream(target);
  ftp.retrieveFile("/pub.tar", fos);
  fos.close();

以下是ftp日志的结果

Mac OS从IntelliJ Idea

开始
downloaded  (30452736 bytes, 21200.67KB/sec)

Mac OS从shell

开始
downloaded  (30452736 bytes, 21471.75KB/sec)

Windows 7(在VMWare中)

downloaded  (30452736 bytes, 65243.15KB/sec)

运行Oracle Java的OpenSuse(在VMWare中)

downloaded  (30452736 bytes, 5274.56KB/sec)

运行OpenJDK的OpenSuse(在VMWare中)

downloaded  (30452736 bytes, 7663.68KB/sec)

Ubuntu 12.04.1 LTS

在连接千兆以太网的另一台PC上运行到同一个局域网。其他Ubuntu机器的行为方式完全相同。我在20分钟后退出了转会。查看转移率。

downloaded  (7077888 bytes, 6.10KB/sec)


edtFTP4j 2.4.0

在此之后,我转到了edtFTP4j。结果好多了。

  FileTransferClient ftp = new FileTransferClient();
  ftp.setRemoteHost("srv0006");
  ftp.setUserName("anonymous");
  ftp.setPassword("asd");
  ftp.connect();
  ftp.downloadFile("/tmp/pub.tar", "/pub.tar");
  ftp.disconnect();

结果发生了显着变化:

Mac OS从IntelliJ Idea

开始
downloaded  (30452736 bytes, 109431.60KB/sec)

Mac OS从shell

开始
downloaded  (30452736 bytes, 110333.66KB/sec)

Windows 7(在VMWare中)

downloaded  (30452736 bytes, 91318.64KB/sec)

运行Oracle Java的OpenSuse(在VMWare中)

downloaded  (30452736 bytes, 89312.46KB/sec)

运行OpenJDK的OpenSuse(在VMWare中)

downloaded  (30452736 bytes, 89041.05KB/sec)

Ubuntu 12.10(在VMWare中)

downloaded  (30452736 bytes, 81154.99KB/sec)

Ubuntu 12.04.1 LTS在i5笔记本电脑上运行,Wifi(50 MBit / s)

downloaded  (30452736 bytes, 2883.84KB/sec)

Ubuntu 12.04.1 LTS在i5笔记本电脑,千兆以太网

上运行
downloaded  (30452736 bytes, 93822.44KB/sec)

Ubuntu 12.04.1 LTS

在前面提到的PC上运行(具有6.10 KB /秒tx速率的PC)

downloaded  (30452736 bytes, 11633.38KB/sec)

我不明白这一点。谁有线索在这里发生什么?

再见,托斯滕......

4 个答案:

答案 0 :(得分:1)

从某些代码中找出它太多了。

它可以是您的默认网络数据包大小(MTU),硬件基础架构,JVM,操作系统配置等等。

你需要在更高层次上玩很多小东西。比如在硬件/操作系统级别上检查您的MTU大小,并将其与API的套接字创建的默认设置相对应。您的基础架构是缓冲还是具有窗口缩放或自动进行病毒检查。

我相信Net Commons缓冲区大小默认为1024,你可以玩它。

除此之外,你需要进入嗅探器,看看发生了什么。可能是交换机配置不正确,使用一个API与另一个API的效果更好。

希望我能给你一个更好的答案,但是当谈到网络性能时,它本身就是一个研究领域......

答案 1 :(得分:0)

这里的一个罪魁祸首是不同平台上的套接字发送和接收缓冲区大小。在Windows上,这些设置低至8k,这极大地限制了TCP吞吐量。一些Windows服务器版本将这些设置为巨大的值;不要问我哪个。 Unix和Linux平台的理智值大约在43-48k之间。

答案 2 :(得分:0)

在许多系统上,FTP的被动模式和主动模式之间也存在很大差异;特别是当服务器只允许一种模式而客户端默认尝试使用另一种模式时。如果我没记错的话,主动模式比被动模式略快,但使用禁止模式可以轻松地减慢传输速度超过一百或一千倍;如果不是简单的阻止。

即使允许这两种模式,防火墙也可以经常减慢被动模式,同时保持不受影响的活动模式(或者它是反向的?)。

答案 3 :(得分:0)

我推测真正的答案是没有人开发出快速复制命令。

要拥有“终极复制/转移”命令,它需要主动监控事物并适应环境。

例如。复制(ref,ref)..为了使这个快速,你不能使用C作为初学者,你需要使用像C语言选项的动态语言。很少有这样的语言存在。

“ref”是对任何东西的引用,复制命令是JIT到机器特定分支,根据源和目标选择适当的路径。

因此,根据ref在运行时的最终结果,实际命令可以是自适应网络传输之间的任何事情,尝试多个路由 memcpy 只需添加一个新的引用(如果src是不可变的,并且target在同一个进程中,并且src可以访问它)。