为什么CF FTP传输速度比标准FTP慢几倍?

| 我有一个ColdFusion应用程序,用于在开发服务器和生产服务器之间传输文件。实际发送文件的代码如下:
ftp = new Ftp();
ftp.setUsername(username);
ftp.setPassword(password);
ftp.setServer(server);
ftp.setTimeout(1800);
ftp.setConnection(\'dev\');
ftp.open();
ftp.putFile(transferMode=\"binary\",localFile=localpath,remoteFile=remotepath);
ftp.close(connection=\'dev\');
使用上述代码发送文件时,我的输出速度接近100KB / s(通过接收服务器上的FileZilla监视)。如果使用Windows命令行FTP工具发送完全相同的文件,则速度将超过1000KB / s。 我创建了一个全新的文件,只带了上面的代码,并且对传输速度没有任何影响,因此我知道它与原始应用程序中的周围代码无关。 那么,是什么原因导致这些低速行驶呢? 编辑:所有测试都已完成,将文件从生产服务器传输到开发服务器。我也尝试使用
<cfftp>
标记而不是cfscript,结果也相同。 编辑#2:我最终使用
cfexecute
,代码如下: 从我的FTP脚本中:
public function sendFiles(required string localpath, required string remotepath) {
    this.writeFtpInstructions(localpath);
    exe = \"C:\\Windows\\system32\\ftp.exe\";
    params = \"-s:\" & request.localapproot & \"/\" & \"upload.txt\";
    outputfile = request.localapproot & \'/ftp.log\';
    timeout = 120;
    Request.cliExec(exe,params,outputfile,timeout);
}

public function writeFtpInstructions(required string localpath) {
    instructions = request.localapproot & \"/\" & \"upload.txt\";
    crlf = chr(13) & chr(10);
    data = \"\";
    data &= \"open \" & this.server & crlf;
    data &= this.username & crlf;
    data &= this.password & crlf;
    data &= \"cd \" & request.remoteapproot & crlf;
    data &= \"put \" & localpath & crlf;
    data &= \"quit\";
    FileWrite(instructions, data);
}
cliExec()
函数(由于在cfscript中没有
cfexecute
等效项,因此必须创建包装器):
<cffunction name=\"cliExec\">
    <cfargument name=\"name\">
    <cfargument name=\"arguments\">
    <cfargument name=\"outputfile\">
    <cfargument name=\"timeout\">
    <cfexecute
        name=\"#name#\"
        arguments=\"#arguments#\"
        outputFile=\"#outputfile#\"
        timeout=\"#timeout#\" />
</cffunction>
    
已邀请:
我一直在寻找,但对于为什么它变慢没有答案。但是,从理论上讲,您应该能够通过Windows命令行使用cfexecute来执行此操作。您甚至可以创建一个批处理文件,然后在一个调用中进行处理。     
以我在CF9上使用cfftp的经验,不可能传输更大的文件。如果在FTP服务器端查看活动的传输,您会注意到传输以最快的速度开始,但是随着越来越多的数据传输,速度不断下降。传输了100 MB之后,还原开始变得非常剧烈,直到最终达到单位数爬取。最终,传输超时并失败。我试图使用330 MB的文件,但发现无法使用cfftp进行传输。我无法使用标准Windows ftp.exe来选择cfexecute,因为它似乎不支持SFTP。 我最终找到了一个通过Coldfusion使用的外部Java类,并决定使用JSch(http://www.jcraft.com/jsch/)。具有讽刺意味的是,CF9似乎将此类用于CFFTP(jsch-0.1.41m.jar),但使用此最新下载版本(jsch-0.1.45.jar)的结果却大不相同。 这是我为概念证明而编写的代码:
<cfscript>
    stAppPrefs = {
        stISOFtp = {
             server = \'sftp.server.com\',
             port = \'22\',
             username = \'youser\',
             password = \'pa$$w0rd\'
        }
    };

    /* Side-Load JSch Java Class (http://www.jcraft.com/jsch/) */
    try {
        // Load Class Using Mark Mandel\'s JavaLoader (http://www.compoundtheory.com/?action=javaloader.index)
        /* 
        Add Mark\'s LoaderClass To The ColdFusion Class Path Under CF Admin:
        Java and JVM : ColdFusion Class Path : C:\\inetpub\\wwwroot\\javaloader\\lib\\classloader-20100119110136.jar
        Then Restart The Coldfusion Application Service
        */
        loader = CreateObject(\"component\", \"javaloader.JavaLoader\").init([expandPath(\"jsch-0.1.45.jar\")]);
        // Initiate Instance
        jsch = loader.create(\"com.jcraft.jsch.JSch\").init();
    }
    catch(any excpt) {          
        WriteOutput(\"Error loading \"\"jsch-0.1.45.jar\"\" java class: \" & excpt.Message & \"<br>\");
        abort;
    }

    /* SFTP Session & Channel */
    try {
        // Create SFTP Session
        session = jsch.getSession(stAppPrefs.stISOFtp.username, stAppPrefs.stISOFtp.server, stAppPrefs.stISOFtp.port);
        // Turn Off & Use Username/Password
        session.setConfig(\"StrictHostKeyChecking\", \"no\");
        session.setPassword(stAppPrefs.stISOFtp.password);
        session.connect();
        // Create Channel To Transfer File(s) On
        channel = session.openChannel(\"sftp\");
        channel.connect();
    }
    catch(any excpt) { 
        WriteOutput(\"Error connecting to FTP server: \" & excpt.Message & \"<br>\");
        abort;
    } 

    // Returns Array Of Java Objects, One For Each Zip Compressed File Listed In Root DIR
    // WriteDump(channel.ls(\'*.zip\'));      
    // Get First Zip File Listed For Transfer From SFTP To CF Server
    serverFile = channel.ls(\'*.zip\')[1].getFilename();

    /* Debug */
    startTime = Now();
    WriteOutput(\"Transfer Started: \" & TimeFormat(startTime, \'hh:mm:ss\') & \"<br>\");
    /* // Debug */

    /* Transfer File From SFTP Server To CF Server */
    try {
        // Create File On Server To Write Byte Stream To
        transferFile = CreateObject(\"java\", \"java.io.File\").init(expandPath(serverFile));
        channel.get(serverFile, CreateObject(\"java\", \"java.io.FileOutputStream\").init(transferFile));
        // Close The File Output Stream
        transferFile = \'\';
    }
    catch(any excpt) { 
        WriteOutput(\"Error transfering file \"\"\" & expandPath(serverFile) & \"\"\": \" & excpt.Message & \"<br>\");
        abort;
    }

    /* Debug */
    finishTime = Now();
    WriteOutput(\"Transfer Finished: \" & TimeFormat(finishTime, \'hh:mm:ss\') & \"<br>\");
    expiredTime = (finishTime - startTime);
    WriteOutput(\"Duration: \" & TimeFormat(expiredTime, \'HH:MM:SS\') & \"<br>\");
    WriteOutput(\"File Size: \" & NumberFormat(Evaluate(GetFileInfo(ExpandPath(serverFile)).size / 1024), \'_,___._\') & \" KB<br>\");
    WriteOutput(\"Transfer Rate: \" & NumberFormat(Evaluate(Evaluate(GetFileInfo(ExpandPath(serverFile)).size / 1024) / Evaluate(((TimeFormat(expiredTime, \'H\') * 60 * 60) + (TimeFormat(expiredTime, \'M\') * 60) + TimeFormat(expiredTime, \'S\')))), \'_,___._\') & \" KB/Sec <br>\");
    /* // Debug */

    channel.disconnect();
    session.disconnect();
    </cfscript>
结果:
Transfer Started: 09:37:57
Transfer Finished: 09:42:01
Duration: 00:04:04
File Size: 331,770.8 KB
Transfer Rate: 1,359.7 KB/Sec
实现的传输速度与使用FileZilla FTP Client和手动下载获得的速度相当。我发现此方法对于cfftp的不足是一种可行的解决方案。     

要回复问题请先登录注册