Spring集成FTP InboundChannelAdapter在网络重置后死亡

时间:2016-05-25 13:52:11

标签: spring ftp spring-integration spring-integration-sftp

我们有一个来自FTP的download文件的用例,并且有一个奇怪的行为,ftp入站适配器在网络重置后停止工作,这是重现问题的步骤:

  1. 启动申请
  2. 应用程序开始从ftp服务器下载文件到本地
  3. 在已定义的本地目录中出现filename.writing文件
  4. 拔出网线(以模拟网络重置情况)
  5. 应用程序停止下载文件(显然没有网络连接)
  6. 插入网线。
  7. 下载未重启或重置,应用程序保持静止..
  8. 根本没有LOG来识别此问题。
  9. 提前致谢!

    更新

    通过添加超时defSession.setConnectTimeout(Integer.valueOf(env.getProperty("ftp.timeout.connect")));

    来解决此问题

    AND 以下代码是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;
        }
    

1 个答案:

答案 0 :(得分:0)

线程很可能仍然挂在读取上 - 如果从计算机上的实际适配器拔出电缆,网络堆栈应该通知java进程套接字已经消失,但是如果从下游拔出电缆路由器,可能没有信号。 jstack将显示线程正在做什么。

您需要在会话工厂设置超时 - 请参阅the documentation和FtpClient javadocs - dataTimeout用于读取。