如何在Spring Boot Java中实现SFTP远程服务器上线通知?
Spring Integration SFTP 服务器恢复上线通知实现方案
Spring Integration SFTP 没有直接内置服务器恢复通知的功能,但可以结合其连接管理机制与Spring生态特性实现需求,以下是具体方案:
核心思路
通过定时检测SFTP连接状态,捕捉从“离线”到“在线”的状态变化,当离线时长超过一小时时触发通知与文件传输任务。
具体实现步骤
1. 基于定时任务的连接状态检测
利用Spring的@Scheduled定时任务,定期尝试获取SFTP会话,判断服务器是否在线:
@Component public class SftpServerMonitor { private final SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory; private boolean serverOnline = true; private long lastOfflineTimestamp; public SftpServerMonitor(SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory) { this.sftpSessionFactory = sftpSessionFactory; } // 每分钟执行一次检测 @Scheduled(fixedRate = 60000) public void checkServerAvailability() { boolean currentStatus = false; try (Session<ChannelSftp.LsEntry> session = sftpSessionFactory.getSession()) { currentStatus = session.isOpen(); } catch (Exception ignored) { // 连接失败视为离线 } // 记录离线开始时间 if (serverOnline && !currentStatus) { lastOfflineTimestamp = System.currentTimeMillis(); } // 检测到恢复上线且离线时长超1小时 if (!serverOnline && currentStatus) { long offlineDuration = System.currentTimeMillis() - lastOfflineTimestamp; if (offlineDuration >= 3600000) { // 3600000毫秒 = 1小时 sendRecoveryNotification(); triggerFileTransferTask(); } } serverOnline = currentStatus; } private void sendRecoveryNotification() { // 替换为实际通知逻辑:邮件、企业微信、短信等 System.out.println("SFTP服务器已恢复上线(离线时长超1小时),请启动文件传输"); } private void triggerFileTransferTask() { // 调用你的SFTP文件传输业务逻辑 } }
2. 利用Spring事件体系解耦通知逻辑
如果需要更灵活的扩展,可以自定义Spring事件,将状态变化与通知逻辑解耦:
// 自定义事件 public class SftpServerRecoveryEvent extends ApplicationEvent { private final long offlineDuration; public SftpServerRecoveryEvent(Object source, long offlineDuration) { super(source); this.offlineDuration = offlineDuration; } public long getOfflineDuration() { return offlineDuration; } }
修改监控类中的通知逻辑,发布事件:
private final ApplicationEventPublisher eventPublisher; // 构造函数注入ApplicationEventPublisher public SftpServerMonitor(SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory, ApplicationEventPublisher eventPublisher) { this.sftpSessionFactory = sftpSessionFactory; this.eventPublisher = eventPublisher; } // 在检测到符合条件的恢复时发布事件 eventPublisher.publishEvent(new SftpServerRecoveryEvent(this, offlineDuration));
编写事件监听器处理通知:
@Component public class SftpRecoveryNotificationListener { @EventListener public void handleSftpRecovery(SftpServerRecoveryEvent event) { // 实现通知逻辑 System.out.printf("SFTP服务器恢复上线,离线时长:%.2f小时%n", event.getOfflineDuration() / 3600000.0); // 触发文件传输 } }
3. 基于入站同步组件的错误回调
如果使用SftpInboundFileSynchronizer进行文件同步,可以通过Advice链捕获连接异常,在恢复时触发通知:
@Bean public SftpInboundFileSynchronizer sftpInboundFileSynchronizer(SessionFactory<ChannelSftp.LsEntry> sessionFactory) { SftpInboundFileSynchronizer synchronizer = new SftpInboundFileSynchronizer(sessionFactory); synchronizer.setRemoteDirectory("/remote/path"); // 添加异常处理Advice synchronizer.setAdviceChain(Collections.singletonList(new SftpConnectionRecoveryAdvice())); return synchronizer; } public class SftpConnectionRecoveryAdvice extends AbstractRequestHandlerAdvice { private boolean wasOffline = false; private long lastOfflineTime; @Override protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception { try { Object result = callback.execute(); // 之前离线现在恢复成功 if (wasOffline) { long offlineDuration = System.currentTimeMillis() - lastOfflineTime; if (offlineDuration >= 3600000) { // 发送通知 } wasOffline = false; } return result; } catch (Exception e) { if (!wasOffline) { lastOfflineTime = System.currentTimeMillis(); wasOffline = true; } throw e; } } }
注意事项
- 确保
SessionFactory配置正确(主机、端口、认证信息等),推荐使用CachingSessionFactory提升连接复用效率。 - 可根据实际场景调整定时检测的频率,避免过于频繁的连接尝试给服务器带来压力。
- 通知逻辑需要根据业务需求实现对应的消息推送渠道,比如集成Spring Boot Mail发送邮件。
内容的提问来源于stack exchange,提问作者Deshan
相关产品推荐
相关产品推荐

