本文介绍了Apache Commons FTPClient挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  try {
logger.trace(尝试连接到服务器...);

//连接到服务器
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(20000);
ftpClient.connect(my-server-host-name);
ftpClient.login(myUser,myPswd);
ftpClient.changeWorkingDirectory(/ loadables /);

//检查失败的连接
if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
{
ftpClient.disconnect();
抛出新的FTPConnectionClosedException(无法连接到FTP服务器。);
}

//日志成功msg
logger.trace(...连接成功。);

//更改到我们轮询文件的可加载/目录
ftpClient.changeWorkingDirectory(/ loadables /);

//表示我们即将轮询
logger.trace(关于检查可加载/对于文件...);

//轮询文件。
FTPFile [] filesList = oFTP.listFiles();
for(FTPFile tmpFile:filesList)
{
if(tmpFile.isDirectory())
continue;

FileOutputStream fileOut = new FileOutputStream(new File(tmp));
ftpClient.retrieveFile(tmpFile.getName(),fileOut);
// ...使用输出流
做一堆事情将文件内容复制到本地
//机器。尽量简洁,但我向你保证这个
//可以工作(除非WAR决定挂起)。
//
//这是因为FTPClient没有出现GET
//这些文件的全部副本,只有FTPFiles类似于
//文件元数据.. 。
}

//表示文件抓取已完成。
logger.trace(File fetch completed。);

//断开并完成。
if(ftpClient.isConnected())
ftpClient.disconnect();

logger.trace(投票已完成);
} catch(Throwable t){
logger.trace(Error:+ t.getMessage());
}

我们计划每分钟运行一次。当部署到Tomcat(7.0.19)时,此代码加载完美,并开始顺利工作。但是,每一次,在某个时候,它似乎只是 hang 。我的意思是:
$ b


  • 不存在堆转储

  • Tomcat仍在运行(我可以看到它的pid,并可以登录到web管理器应用程序)

  • 在经理应用程序内部,我可以看到我的WAR仍在运行/启动

  • catalina.out 和我的特定于应用程序的日志显示没有任何异常被抛出的迹象



所以JVM仍在运行。 Tomcat仍在运行,我部署的WAR仍在运行,但它只是挂起。有时运行2小时然后挂起;其他时间它运行几天然后挂起。但是当它挂起时,它会在读取关于检查可加载文件/文件... (我在日志中看到)和该行读取文件抓取完成。(我看不到)。



这告诉我在实际轮询/获取文件,这种指向与方向相同我能够发现FTPClient的死锁问题。这让我想知道这些问题是否是相同的问题(如果是,我会很乐意删除这个问题!)。然而,我不认为他们是相同的(我在日志中看不到相同的例外情况)。



A co工作人员提到这可能是被动与主动FTP之间的事情。不知道其中的差别,我对FTPClient字段 ACTIVE_REMOTE_DATA_CONNECTION_MODE PASSIVE_REMOTE_DATA_CONNECTION_MODE 等有些困惑,我知道这是什么想到这是一个潜在的问题。



因为我捕获 Throwable s作为在这里最后的手段,如果出现问题,我会希望在日志中看到 。 Ergo,我觉得这是一个明确的悬挂问题。



任何想法?不幸的是,我对这里的FTP内部知识不够了解,无法做出明确的诊断。这可能是服务器端的东西吗?与FTP服务器有关吗?

解决方案

这可能是一些事情,但你朋友的建议是值得的。 >

尝试 ftpClient.enterLocalPassiveMode(); 以查看它是否有帮助。



我还建议将断开连接放在最后中,以便它从来没有留下一个连接。

We are using the following Apache Commons Net FTP code to connect to an FTP server, poll some directories for files, and if files are found, to retrieve them to the local machine:

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());
}

We have this scheduled to run every minute, on the minute. When deployed to Tomcat (7.0.19) this code loads up perfectly fine and begins working without a hitch. Every time though, at some point or another, it seems to just hang. By that I mean:

  • No heap dumps exist
  • Tomcat is still running (I can see its pid and can log into the web manager app)
  • Inside the manager app, I can see my WAR is still running/started
  • catalina.out and my application-specific log show no signs of any exceptions being thrown

So the JVM is still running. Tomcat is still running, and my deployed WAR is still running, but its just hanging. Sometimes it runs for 2 hours and then hangs; other times it runs for days and then hangs. But when it does hang, it does so between the line that reads About to check loadables/ for files... (which I do see in the logs) and the line that reads File fetch completed. (which I don't see).

This tells me the hang occurs during the actual polling/fetching of the files, which kind of points me in the same direction as this question that I was able to find which concerns itself with FTPClient deadlocking. This has me wondering if these are the same issues (if they are, I'll happily delete this question!). However I don't think believe they're the same (I don't see the same exceptions in my logs).

A co-worker mentioned it might be a "Passive" vs. "Active" FTP thing. Not really knowing the difference, I am a little confused by the FTPClient fields ACTIVE_REMOTE_DATA_CONNECTION_MODE, PASSIVE_REMOTE_DATA_CONNECTION_MODE, etc. and didn't know what SO thought about that as being a potential issue.

Since I'm catching Throwables as a last resort here, I would have expected to see something in the logs if something is going wrong. Ergo, I feel like this is a definite hang issue.

Any ideas? Unfortunately I don't know enough about FTP internals here to make a firm diagnosis. Could this be something server-side? Related to the FTP server?

解决方案

This could be a number of things, but your friend's suggestion would be worthwhile.

Try ftpClient.enterLocalPassiveMode(); to see if it helps.

I would also suggest to put the disconnect in the finally block so that it never leaves a connection out there.

这篇关于Apache Commons FTPClient挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 10:38