java - Apache Commons FTPClient 挂起

标签 java ftp ftp-client apache-commons-net

我们正在使用以下 Apache Commons Net FTP 代码连接到 FTP 服务器,轮询一些目录中的文件,如果找到文件,则将它们检索到本地计算机:

try {
logger.trace("Attempting to connect to server...");

// Connect to server
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(20000);
ftpClient.connect("my-server-host-name");
ftpClient.login("myUser", "myPswd");
ftpClient.changeWorkingDirectory("/loadables/");

// Check for failed connection
if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
{
    ftpClient.disconnect();
    throw new FTPConnectionClosedException("Unable to connect to FTP server.");
}

// Log success msg
logger.trace("...connection was successful.");

// Change to the loadables/ directory where we poll for files
ftpClient.changeWorkingDirectory("/loadables/");    

// Indicate we're about to poll
logger.trace("About to check loadables/ for files...");

// Poll for files.
FTPFile[] filesList = oFTP.listFiles();
for(FTPFile tmpFile : filesList)
{
    if(tmpFile.isDirectory())
        continue;

    FileOutputStream fileOut = new FileOutputStream(new File("tmp"));
    ftpClient.retrieveFile(tmpFile.getName(), fileOut);
    // ... Doing a bunch of things with output stream
    // to copy the contents of the file down to the local
    // machine. Ommitted for brevity but I assure you this
    // works (except when the WAR decides to hang).
    //
    // This was used because FTPClient doesn't appear to GET
    // whole copies of the files, only FTPFiles which seem like
    // file metadata...
}

// Indicate file fetch completed.
logger.trace("File fetch completed.");

// Disconnect and finish.
if(ftpClient.isConnected())
    ftpClient.disconnect();

logger.trace("Poll completed.");
} catch(Throwable t) {
    logger.trace("Error: " + t.getMessage());
}

我们计划每分钟每分钟运行一次。当部署到 Tomcat (7.0.19) 时,此代码加载得非常好,并且可以顺利开始工作。但每次,在某个时候,它似乎只是挂起。我的意思是:

  • 不存在堆转储
  • Tomcat 仍在运行(我可以看到它的 pid 并且可以登录到 Web 管理器应用程序)
  • 在管理器应用中,我可以看到我的 WAR 仍在运行/启动
  • catalina.out 和我的特定于应用程序的日志显示没有任何异常被抛出的迹象

所以 JVM 仍在运行。 Tomcat 仍在运行,我部署的 WAR 仍在运行,但它只是挂起。有时运行 2 小时然后挂起;其他时候它会运行几天然后挂起。但是当它挂起时,它会在读取 About to check loadables/for files... 的行(我确实在日志中看到)和读取 File fetch 的行之间这样做完成。(我没看到)。

这告诉我在文件的实际轮询/获取过程中发生了挂起,这使我指向与 this question 相同的方向我能够找到与 FTPClient 死锁有关的问题。这让我想知道这些问题是否相同(如果是,我会很乐意删除这个问题!)。但是我不认为相信它们是相同的(我在我的日志中没有看到相同的异常)。

一位同事提到它可能是“被动”与“主动”的 FTP 事情。不知道有什么区别,我对 FTPClient 字段 ACTIVE_REMOTE_DATA_CONNECTION_MODEPASSIVE_REMOTE_DATA_CONNECTION_MODE 等感到有些困惑,并且不知道 SO 认为这是一个潜在问题.

由于我在这里将 Throwable 作为最后的手段,因此如果出现问题,我本来希望在日志中看到 something。因此,我觉得这是一个明确的挂起问题。

有什么想法吗?不幸的是,我对这里的 FTP 内部知识知之甚少,无法做出明确的诊断。这可能是服务器端的东西吗?跟FTP服务器有关吗?

最佳答案

这可能是很多事情,但你 friend 的建议是值得的。

试试 ftpClient.enterLocalPassiveMode(); 看看是否有帮助。

我还建议将断开连接放在 finally block 中,这样它就不会留下连接。

关于java - Apache Commons FTPClient 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9706968/

相关文章:

java - 此方法应该反转 ArrayList 中的数字

java - 如何让 Tomcat 接受 URL 中未转义的括号?

PHP - 无法连接到 FTP - 隐式 SSL 端口 990

ftp - PHPstorm FTP无法上传文件

java - Apache commons-net FTP - 将文件上传到安全 FTP IIS

php - 下载大目录时 FTP 出现问题

java - 如何暂停然后恢复一个线程?

java - JDBC MySQL 提示连接太多

java - 如何在java中获取ftp传输速率?

java - 无法使用 Apache commons-net-3.1 在 FTP 上上传大文件