2016-05-25 25 views
0

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

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

在此先感谢!

UPDATE

此问题应该通过FTP客户端读取关于添加超时defSession.setConnectTimeout(Integer.valueOf(env.getProperty("ftp.timeout.connect")));

AND下面的代码是一个工作实施例被固定。

以下是代码片段:

@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; 
    } 

回答

0

最有可能的线程仍然挂在读 - 如果你拉从实际适配器的电缆在电脑上,网络堆栈应通知的java进程插座不见了,但是如果从下游路由器拉出电缆,则可能没有信号。 jstack将显示线程正在做什么。

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

+0

谢谢!在我们的例子中,电缆已从下游拉出,我会尝试并告诉您是否这是原因,另一个问题是,为什么在spring-integration-ftp模块中很少有日志记录,我们该如何改进它? – Jaiwo99

+0

我不确定你的意思是“少数” - 如果线程在读取时“卡住”,它不能记录任何东西。运行正常时,您可以使用DEBUG日志记录来获取更多日志。 –

+0

我们设置了'logging.level.org.springframework.integration:TRACE',我得到的唯一日志是'2016-05-25 16:32:11.677 DEBUG 24075 --- [ask-scheduler-5] osifsDefaultFtpSessionFactory:Connected到服务器[IP]' – Jaiwo99