次の 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 と「アクティブ」FTP の違いかもしれないと言っていました。違いがよくわからないので、FTPClient フィールドACTIVE_REMOTE_DATA_CONNECTION_MODE
、PASSIVE_REMOTE_DATA_CONNECTION_MODE
などに少し混乱し、SO がこれを潜在的な問題としてどう考えているのかわかりませんでした。
私はThrowable
最後の手段としてsを捕まえているので、何か何か問題が起きている場合はログに記録してください。したがって、これは明らかにハングの問題であるように思われます。
何かアイデアはありますか? 残念ながら、FTP 内部について十分な知識がないため、確実な診断を下すことができません。これはサーバー側の問題でしょうか? FTP サーバーに関連しているのでしょうか?
ベストアンサー1
これにはさまざまなことが考えられますが、友人の提案は価値があるでしょう。
ftpClient.enterLocalPassiveMode();
役立つかどうか試してみてください。
また、finally
ブロックに切断を入れるそうすれば、接続が外部に残らないようになります。