迁移至Spring Boot 3后,如何处理服务器的keepalive@openssh.com请求?
问题描述
我们团队的应用每日通过Spring Integration SFTP从远程服务器拉取并处理一次文件,近期从Spring Boot 2.7迁移至Spring Boot 3后,每分钟都会生成如下WARN级别的日志:
2023-08-15T15:00:48.427+02:00 WARN 21256 --- []-nio2-thread-3] i.DefaultSftpClient$SftpChannelSubsystem : handleUnknownChannelRequest(SftpChannelSubsystem[id=0, recipient=0]-ClientSessionImpl[<username>@<host>/<ip>:<port>][sftp]) Unknown channel request: keepalive@openssh.com[want-reply=true] 2023-08-15T15:01:48.430+02:00 WARN 21256 --- [-nio2-thread-13] i.DefaultSftpClient$SftpChannelSubsystem : handleUnknownChannelRequest(SftpChannelSubsystem[id=0, recipient=0]-ClientSessionImpl[<username>@<host>/<ip>:<port>][sftp]) Unknown channel request: keepalive@openssh.com[want-reply=true]
该警告由服务器向客户端发送的keepalive@openssh.com请求触发,Spring Boot 2.7版本中无此问题。虽然不影响文件拉取功能,但大量无用警告会淹没日志中的重要信息。当前使用的SessionFactory配置如下:
@Bean public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() { final DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true); factory.setHost(sftpHost); factory.setPort(sftpPort); factory.setUser(sftpUser); if (sftpPrivateKey != null) { factory.setPrivateKey(sftpPrivateKey); factory.setPrivateKeyPassphrase(sftpPrivateKeyPassphrase); } else { factory.setPassword(sftpPassword); } factory.setAllowUnknownKeys(true); return new CachingSessionFactory<>(factory); }
解决方案
方案1:屏蔽目标类的WARN日志(最简单直接)
直接通过日志配置降低org.apache.sshd.client.channel.DefaultSftpClient$SftpChannelSubsystem类的日志级别至ERROR,即可过滤掉该类的WARN警告。
配置示例(application.yml)
logging: level: org.apache.sshd.client.channel.DefaultSftpClient$SftpChannelSubsystem: ERROR
配置示例(logback-spring.xml)
<logger name="org.apache.sshd.client.channel.DefaultSftpClient$SftpChannelSubsystem" level="ERROR" />
方案2:自定义处理器响应keepalive请求(从根源解决)
通过扩展DefaultSftpSessionFactory,为SftpClient添加针对keepalive@openssh.com请求的处理器,让客户端能正确回复服务器的keepalive请求,从而消除警告。修改后的SessionFactory配置如下:
@Bean public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() { final DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true); factory.setHost(sftpHost); factory.setPort(sftpPort); factory.setUser(sftpUser); if (sftpPrivateKey != null) { factory.setPrivateKey(sftpPrivateKey); factory.setPrivateKeyPassphrase(sftpPrivateKeyPassphrase); } else { factory.setPassword(sftpPassword); } factory.setAllowUnknownKeys(true); // 注册keepalive请求处理器 factory.setSftpClientFactory(clientSession -> { SftpClient client = DefaultSftpClient.newInstance(clientSession); client.getChannel().addChannelRequestHandler("keepalive@openssh.com", (channel, request, wantReply) -> { if (wantReply) { channel.sendSuccess(); } return true; }); return client; }); return new CachingSessionFactory<>(factory); }
方案3:调整服务器端keepalive配置(需服务器权限)
若拥有SFTP服务器的管理权限,可修改服务器的keepalive相关配置(例如OpenSSH的ClientAliveInterval参数),或关闭向客户端发送keepalive@openssh.com通道请求的功能,从根源避免该警告产生。
内容的提问来源于stack exchange,提问作者Albin Friedner
相关产品推荐
相关产品推荐

