Spring 在 Docker 容器中集成 FTP:未触发流程

Spring Integration FTP in Docker container: not triggering flow

我花了很长时间才弄清楚我的问题出在哪里。我可以在本地 运行,我也在本地构建了 .jar 和 运行。

我的集成流程设置如下

@Bean
IntegrationFlow integrationFlow(final DataSource datasource) {
return IntegrationFlows.from(
    Ftp.inboundStreamingAdapter(template())
        .remoteDirectory("/folder/")
        .patternFilter("file_name.txt")
        .filter(
            new FtpPersistentAcceptOnceFileListFilter(metadataStore(datasource), "")),
    spec -> spec.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)))
    .transform(streamToBytes())
    .handle(handler())
    .get()
}

@Bean
FtpRemoteFileTemplate template() {
  return new FtpRemoteFileTemplate(ftpSessionFactory());
}

@Bean
public StreamTransformer streamToBytes() {
  return new StreamTransformer(); // transforms to byte[]
}

@Bean
public ConcurrentMetadataStore metadataStore(final DataSource dataSource) {
  return new JdbcMetadataStore(dataSource);
}

@Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
  DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
  sf.setHost(host);
  sf.setPort(port);
  sf.setUsername(userName);
  sf.setPassword(password);
  return sf;
}

我在 application.yml

中设置了数据源和 ftp 信息

当我在本地运行时,我没有任何问题。当我 运行 gradle build 和 运行 我的 .jar 使用几个不同的 openjdk 版本(8u181、8u191、11.04)时,我没有任何问题。

当我 运行 在 docker 容器中使用我的 .jar 文件时,问题出现了。

我的docker文件

FROM openjdk:8u212-jdk-alpine
WORKDIR /app

COPY build/libs/app-1.0.jar .

RUN apk add --update ttf-dejavu && rm -rf /var/cache/apk/*

ENTRYPOINT ["java", "-jar", "app-1.0.jar"]

我打开 DEBUG 并观察输出。

运行 在本地和 运行 构建 .jar,我可以看到轮询器正在工作并且它触发了对 metadataStore [=66] 的 SQL 查询=] 已在我的远程数据库中创建 (postgresql).

运行 在 docker 容器中,我没有看到 sql 查询是 运行。这告诉我其中某处存在问题。

在我的启动日志中进行调试时,控制台中的 INFOs 和 WARNs 与本地 运行ning 相同,运行ning 内置 .jar,或 运行ning 在 docker 容器中。 这条信息消息可能会有所帮助

Bean with key 'metadataStore' has been registered as an MBean but has no exposed attributes or operations

我通过尝试连接到无效主机来检查是否存在隐藏的 SessionFactory 连接问题,但我确实在我的 docker 容器中遇到了无效主机的异常。所以我可以自信地说 FTP 连接是有效的并且 运行 是正确的主机和端口。

我认为这与轮询器或我的数据源有关。

在这个应用程序中,我也在运行宁Spring使用JDBC和JPA的数据休息,在不同的环境中使用数据源bean会不会有任何问题?图书馆?

如有任何帮助或指导,我们将不胜感激。

所以 DefaultFtpSessionFactory 的默认客户端模式是 "ACTIVE",但在我的例子中,在 docker 容器内,客户端模式必须设置为 "PASSIVE"

为此,我需要向 DefaultFtpSessionFactory 添加一行代码 您必须将客户端模式设置为 2 ... sf.setClientMode(2); 下面是最终的 DefaultFtpSessionFactory bean。

@Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
  DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
  sf.setHost(host);
  sf.setPort(port);
  sf.setUsername(userName);
  sf.setPassword(password);
  sf.setClientMode(2);

  return sf;
}