0

我们有一个使用downloadFTP 文件的用例,在网络重置后 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 回答