0

FTP からのファイルへの使用例がdownloadあり、ネットワークのリセット後に ftp インバウンド アダプターが動作を停止するという奇妙な動作があります。問題を再現する手順は次のとおりです。

  1. アプリケーションを開始
  2. アプリケーションは、ftp サーバーからローカルへのファイルのダウンロードを開始します
  3. 定義されたローカル ディレクトリに表示される filename.writing ファイルがあります
  4. ネットワーク ケーブルを引き抜きます (ネットワークのリセット状況をシミュレートするため)。
  5. アプリケーションがファイルのダウンロードを停止します (明らかにネットワーク接続がありません)
  6. ネットワークケーブルを接続します。
  7. ダウンロードは再開またはリセットされず、アプリケーションは静止したままです..
  8. LOGこの問題を特定する方法はまったくありません。

前もって感謝します!

アップデート

この問題は、タイムアウトを追加することで修正する必要がありますdefSession.setConnectTimeout(Integer.valueOf(env.getProperty("ftp.timeout.connect")));

および以下のコードは、FTP 読み取りクライアントでの動作例です。

コード スニペットは次のとおりです。

    @Bean
    public DefaultFtpSessionFactory ftpSessionFactory() {
        DefaultFtpSessionFactory defSession = new DefaultFtpSessionFactory();
        defSession.setUsername(env.getProperty("ftp.username"));
        defSession.setPassword(env.getProperty("ftp.password"));
        defSession.setPort(21);
        defSession.setHost(env.getProperty("ftp.host"));

        defSession.setClientMode(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE);
        defSession.setControlEncoding("UTF-8");

        return defSession;
    }

    @Bean
    PollableChannel ftpChannel() {
        return new QueueChannel(Integer.valueOf(env.getProperty("ftp.channel.size")));
    }

    @Bean
    public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
        FtpInboundFileSynchronizer ftpInboundFileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
        ftpInboundFileSynchronizer.setDeleteRemoteFiles(Boolean.valueOf(env.getProperty("ftp.directory.delete")));

        FtpRegexPatternFileListFilter ftpRegexPatternFileListFilter = new FtpRegexPatternFileListFilter(pattern);
        ftpInboundFileSynchronizer.setFilter(ftpRegexPatternFileListFilter);
        ftpInboundFileSynchronizer.setRemoteDirectory(env.getProperty("ftp.directory.remote"));

        return ftpInboundFileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(value = "ftpChannel")
    public FtpInboundFileSynchronizingMessageSource ftpInboundFileSynchronizingMessageSource() {
        FtpInboundFileSynchronizingMessageSource ftpInboundFileSynchronizingMessageSource = new FtpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
        ftpInboundFileSynchronizingMessageSource.setLoggingEnabled(true);
        ftpInboundFileSynchronizingMessageSource.setCountsEnabled(true);
        ftpInboundFileSynchronizingMessageSource.setAutoCreateLocalDirectory(true);
        ftpInboundFileSynchronizingMessageSource.setLocalDirectory(new File(env.getProperty("ftp.directory.local")));

        return ftpInboundFileSynchronizingMessageSource;
    }

    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata defaultPoller() {
        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setErrorHandler(t -> log.error("Failed to retrieve data from FTP: {}", t.getMessage(), t));
        pollerMetadata.setTrigger(new PeriodicTrigger(60, TimeUnit.SECONDS));
        return pollerMetadata;
    }
4

1 に答える 1

0

ほとんどの場合、スレッドはまだ読み取りでハングしています。コンピューターの実際のアダプターからケーブルを引き抜くと、ネットワーク スタックは Java プロセスにソケットがなくなったことを通知するはずですが、ダウンストリーム ルーターからケーブルを引き抜くと、無信号かもしれません。jstack は、スレッドが何をしているかを示します。

セッション ファクトリでタイムアウトを設定する必要があります。ドキュメントと FtpClient javadocs を参照してください。これdataTimeoutは読み取りに使用されます。

于 2016-05-25T14:40:44.100 に答える