java - 如何确保 SFTP session 始终在 spring-batch 结束时关闭

标签 java spring spring-boot spring-integration spring-batch

我的应用程序基于 spring-boot 2.1.6,配备 spring-batch( block 方法)和 spring-integration 来处理 SFTP。

高级功能是从数据库获取数据,生成文本文件,然后通过 SFTP 发送它,此任务每 30 分钟运行一次。

此应用程序已在生产环境中运行了一段时间,但如果我看到日志,则存在有关 ssh_msg_disconnect 11 空闲连接 的错误。它会一直保持这种状态,直到我重新启动应用程序。

下面是我的应用程序代码:

SftpConfig.java

@Configuration
public class SftpConfig {

    @Autowired
    ApplicationProperties applicationProperties;

    @Bean
    public SessionFactory<LsEntry> sftpSessionFactory() {
        final DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost(applicationProperties.getSftp().getHost());
        factory.setUser(applicationProperties.getSftp().getUser());
        factory.setPassword(applicationProperties.getSftp().getPass());
        factory.setAllowUnknownKeys(true);

        return new CachingSessionFactory<>(factory);
    }

    @Bean
    @ServiceActivator(inputChannel = "toSftpChannel", adviceChain = "retryAdvice")
    public MessageHandler handler() {
        final SftpMessageHandler handler = new SftpMessageHandler(this.sftpSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression(applicationProperties.getSftp().getPath()));
        handler.setFileNameGenerator((final Message<?> message) -> {
            if (message.getPayload() instanceof File) {
                return ((File) message.getPayload()).getName();
            } else {
                throw new IllegalArgumentException("File expected as payload.");
            }
        });

        return handler;
    }

    @Bean
    public RequestHandlerRetryAdvice retryAdvice() {
        final RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
        final RetryTemplate retryTemplate = new RetryTemplate();
        final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(NumberConstants.FIVE);
        retryTemplate.setRetryPolicy(retryPolicy);
        advice.setRetryTemplate(retryTemplate);

        return advice;
    }

    @MessagingGateway
    public interface UploadGateway {

        @Gateway(requestChannel = "toSftpChannel")
        void upload(File file);
    }

}

发送文件到sftp的步骤


@Autowired
UploadGateway uploadGateway;

private boolean uploadToSharedFolderSuccess(final PaymentStatus paymentStatus, final String strLocalTmpPath) {
        try {
            final File fileLocalTmpFullPath = new File(strLocalTmpPath);
            uploadGateway.upload(fileLocalTmpFullPath);
        } catch (final Exception e) {
            paymentStatus.setStatus(ProcessStatus.ERROR.toString());
            paymentStatus.setRemark(StringUtil.appendIfNotEmpty(paymentStatus.getRemark(),
                    "Error during upload to shared folder - " + e.getMessage()));
        }
        return !StringUtils.equalsIgnoreCase(ProcessStatus.ERROR.toString(), paymentStatus.getStatus());
    }

从错误中,我知道似乎我打开了太多连接。但我不确定如何检查 spring-batch 的每个末端的连接是否都已关闭。

最佳答案

如果您不将 session 工厂包装在 CachingSessionFactory 中, session 将在每次使用后关闭。

@Bean
public DefaultSftpSessionFactory sftpSessionFactory() {
    final DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost(applicationProperties.getSftp().getHost());
    factory.setUser(applicationProperties.getSftp().getUser());
    factory.setPassword(applicationProperties.getSftp().getPass());
    factory.setAllowUnknownKeys(true);

    return factory;
}

关于java - 如何确保 SFTP session 始终在 spring-batch 结束时关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57434702/

相关文章:

java - 带临时表的 Spring JDBCTemplate

java - 无法使用 Spring Cacheable 在 Aerospike Cache 中添加记录

spring - 如何将自定义 ApplicationContextInitializer 添加到 Spring Boot 应用程序?

java - 如何根据 boolean 值列过滤 JTable 中的行?

java - Arity.jar 中的语法异常

spring integration http出站网关超时处理

java - 当更新同时运行时,乐观锁定不起作用 Spring Data JPA

postgresql - 如果参数为空,则无法查询 SQL 忽略部分 WHERE

java - 如何将数据从列表适配器发送到 android 中的 Activity ?

java - 如何使用按钮从主窗口启动窗口