次の 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 completed.
(表示されません) の間で停止します。
これは、ファイルの実際のポーリング/フェッチ中にハングが発生したことを示しています。これは、FTPClient のデッドロックに関係することを見つけることができたこの質問と同じ方向性を示しています。これは、これらが同じ問題であるかどうか疑問に思っています (もしそうなら、喜んでこの質問を削除します! )。ただし、それらが同じであるとは思いません(ログに同じ例外が表示されません)。
同僚は、それが「パッシブ」対「アクティブ」な FTP である可能性があると述べました。違いがよくわからないので、FTPClientフィールドなどに少し混乱しており、ACTIVE_REMOTE_DATA_CONNECTION_MODE
SOPASSIVE_REMOTE_DATA_CONNECTION_MODE
がそれを潜在的な問題と考えていることを知りませんでした。
ここでは最後の手段として s をキャッチしているので、何か問題が発生した場合はログに何かThrowable
が表示されると予想していました。エルゴ、これは明確なハングの問題だと思います。
何か案は?残念ながら、ここでの FTP の内部については、確固たる診断を下すのに十分な知識がありません。これはサーバー側のものでしょうか?FTP サーバーに関連していますか?