Skip to content

SFTP Session Factory 配置指南

概述

SFTP Session Factory 是 Spring Integration SFTP 适配器的核心组件,负责创建和管理 SFTP 会话连接。本教程将详细讲解如何配置和使用 SFTP Session Factory,采用 Kotlin 和现代 Spring 最佳实践。

IMPORTANT

从 Spring Integration 3.0 开始,会话默认不再缓存,必须显式配置缓存策略。详见 SFTP Session Caching

基础配置

创建 Session Factory Bean

配置 SFTP 适配器前,必须先配置 SFTP Session Factory:

kotlin
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory

@Configuration
class SftpConfig {
    
    @Bean
    fun sftpSessionFactory(): DefaultSftpSessionFactory {
        return DefaultSftpSessionFactory(false).apply {
            host = "localhost"
            port = 22
            user = "kermit"
            privateKey = ClassPathResource("META-INF/keys/sftpTest")
            privateKeyPassphrase = "springIntegration"
        }
    }
}

代码说明

  • DefaultSftpSessionFactory(false):参数表示不使用共享会话
  • privateKey:使用类路径资源加载私钥文件
  • privateKeyPassphrase:私钥的密码短语
  • host/user:SFTP 服务器的主机和用户名(必需)

最佳实践

使用 Spring 的属性占位符配置敏感信息,避免硬编码:

properties
# application.properties
sftp.host=localhost
sftp.port=22
sftp.user=kermit
sftp.privateKeyPath=classpath:META-INF/keys/sftpTest
sftp.passphrase=springIntegration

然后在配置中引用:

kotlin
@Value("\${sftp.host}") lateinit var host: String
@Value("\${sftp.privateKeyPath}") lateinit var privateKeyPath: String
// ...

核心配置属性

连接与认证配置

属性类型必填默认值说明
hostString-SFTP 服务器主机地址
portInt22SFTP 服务器端口
userString-认证用户名
passwordString-密码认证方式
privateKeyResource-私钥文件资源
privateKeyPassphraseString-私钥密码短语
knownHostsResourceResource-已知主机密钥库
allowUnknownKeysBooleanfalse是否允许未知主机密钥

CAUTION

如果设置了 userInteraction 属性,则不能再使用 privateKeyPassphrase,密码短语需通过交互对象获取。

高级连接配置

kotlin
@Bean
fun advancedSftpSessionFactory(): DefaultSftpSessionFactory {
    return DefaultSftpSessionFactory(true).apply { // [!code highlight] // 启用共享会话
        host = "sftp.example.com"
        user = "user"
        privateKey = FileSystemResource("/keys/id_rsa")
        timeout = 60000 // 60秒超时
        allowUnknownKeys = true // [!code warning] // 生产环境慎用
        sftpVersionSelector = SftpVersionSelector.SFTP_V3 // 指定协议版本
        
        // 自定义SSH客户端配置
        sshClientConfigurer = { sshClient ->
            sshClient.nioWorkers = 4
            PropertyResolverUtils.updateProperty(
                sshClient, 
                CoreModuleProperties.MAX_PACKET_SIZE.name, 
                32768
            )
        }
    }
}

SFTP 会话缓存

为什么需要缓存

每次请求都创建新会话会导致性能问题,特别是在频繁操作时。启用缓存可显著提升性能:

配置缓存会话工厂

kotlin
import org.springframework.integration.file.remote.session.CachingSessionFactory

@Bean
fun cachingSftpSessionFactory(
    sftpSessionFactory: DefaultSftpSessionFactory
): CachingSessionFactory {
    return CachingSessionFactory(sftpSessionFactory).apply {
        sessionCacheSize = 10 // 缓存会话数量
        sessionWaitTimeout = 60000 // 等待会话超时(毫秒)
        testSession = true // 获取会话时测试有效性
    }
}

WARNING

共享会话必须配合缓存使用
当启用共享会话 (isSharedSession=true) 时,必须使用缓存会话工厂,否则连接会在操作完成后立即关闭,导致后续操作失败。

高级用法

自定义 SFTP 客户端

从 Spring Integration 6.1.3 开始,支持自定义 SFTP 客户端:

kotlin
class CustomSftpSessionFactory : DefaultSftpSessionFactory(false) {
    
    override fun createSftpChannelSubsystem(clientSession: ClientSession): ChannelSubsystem {
        val channel = super.createSftpChannelSubsystem(clientSession)
        
        // 添加自定义请求处理器
        channel.addRequestHandler { channel, request, wantReply, buffer ->
            when (request) {
                "custom-request" -> {
                    // 处理自定义请求
                    if (wantReply) {
                        channel.writePacket(Buffer().putString("ACK"))
                    }
                    return@addRequestHandler true
                }
                else -> return@addRequestHandler false
            }
        }
        return channel
    }
}

// 在配置中使用自定义工厂
@Bean
fun customSftpSessionFactory(): CustomSftpSessionFactory {
    return CustomSftpSessionFactory().apply {
        host = "localhost"
        user = "user"
        // ...其他配置
    }
}

代理服务器支持

通过 HostConfigEntry 配置代理跳转:

kotlin
@Bean
fun proxiedSftpSessionFactory(): DefaultSftpSessionFactory {
    val hostConfig = HostConfigEntry().apply {
        host = "target-server"
        username = "user"
        proxyJump = "proxy-server"
    }
    
    return DefaultSftpSessionFactory(false).apply {
        hostConfig = hostConfig
        // 代理服务器认证配置
        password = "proxyPassword"
    }
}

常见问题解决方案

连接失败问题排查

问题现象可能原因解决方案
Connection refused服务器地址/端口错误确认主机和端口正确
Auth fail认证信息错误检查用户名/密码/密钥
UnknownHostKey主机密钥未识别设置 allowUnknownKeys=true 或提供 knownHostsResource
SocketTimeoutException网络问题或防火墙增加 timeout 值,检查网络连接
No such file路径错误检查远程目录是否存在

性能优化建议

kotlin
@Bean
fun optimizedSftpFactory(): CachingSessionFactory {
    val factory = DefaultSftpSessionFactory(true).apply { // [!code highlight] // 共享会话
        host = "sftp.example.com"
        user = "user"
        // ...其他配置
    }
    
    return CachingSessionFactory(factory).apply {
        sessionCacheSize = 15 // 根据并发需求调整
        sessionWaitTimeout = 30000
        poolSize = 10 // 连接池大小
    }
}

TIP

监控建议
使用 Spring Boot Actuator 监控 SFTP 连接:

  1. 添加依赖:implementation 'org.springframework.boot:spring-boot-starter-actuator'
  2. 配置端点:management.endpoints.web.exposure.include=health,sftpsessions
  3. 访问 /actuator/sftpsessions 查看会话状态

总结

SFTP Session Factory 是 Spring Integration SFTP 操作的核心组件,正确配置可确保安全高效的远程文件操作:

  1. 基础配置:设置主机、用户和认证信息
  2. 会话缓存:生产环境必须配置缓存提升性能
  3. 共享会话:高并发场景启用共享会话(需配合缓存)
  4. 高级定制:支持自定义 SSH 客户端和 SFTP 处理逻辑
  5. 最佳实践
    • 使用属性占位符管理敏感信息
    • 生产环境禁用 allowUnknownKeys
    • 根据并发需求调整连接池大小
kotlin
// 完整的最佳实践配置示例
@Bean
fun sftpSessionFactory(
    @Value("\${sftp.host}") host: String,
    @Value("\${sftp.user}") user: String,
    @Value("\${sftp.privateKey}") privateKey: Resource
): CachingSessionFactory {
    val factory = DefaultSftpSessionFactory(true).apply {
        this.host = host
        this.user = user
        this.privateKey = privateKey
        port = 22
        timeout = 30000
        allowUnknownKeys = false
        knownHostsResource = ClassPathResource("known_hosts")
    }
    
    return CachingSessionFactory(factory).apply {
        sessionCacheSize = 20
        poolSize = 15
    }
}
不同版本行为变化(点击展开)
版本会话缓存共享会话建议配置
❤️.0默认启用不支持无需额外配置
3.0+默认禁用支持必须显式配置缓存
6.1.3+默认禁用支持支持自定义 SFTP 客户端

通过本教程,您应该能够根据实际需求配置安全高效的 SFTP Session Factory。在实际使用中,请根据服务器性能和网络条件调整连接池和超时设置。