使用连接池和JSCH

时间:2012-10-08 10:40:00

标签: java multithreading connection-pooling sftp jsch

我正在使用JSCH进行文件上传sftp。在当前状态下,每个线程在需要时打开和关闭连接。

是否可以使用与JSCH的连接池以避免因大量连接打开和关闭而导致的开销?

以下是从线程内部调用的函数示例

 public static void file_upload(String filename) throws IOException {
    JSch jsch = new JSch();
    Session session = null;
    try {
        session = jsch.getSession("user", "server_name", 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword("super_secre_password");
        session.connect();

        Channel channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp sftpChannel = (ChannelSftp) channel;

        FileInputStream inputSrr = new FileInputStream(filename);  
        try {  
            sftpChannel.put(inputSrr, "/var/temp/"+filename);  
        } catch (SftpException e) {  
            e.printStackTrace();  

        } finally {  
            if (inputSrr != null) {  
                inputSrr.close();  
            }  
        }  

        sftpChannel.exit();
        session.disconnect();
    } catch (JSchException e) {
        e.printStackTrace();
    } catch (SftpException e) {
        e.printStackTrace();
    }
}

3 个答案:

答案 0 :(得分:5)

为此我更喜欢commons-pool。 ;)

答案 1 :(得分:4)

这是Ssh连接池的一个实现 http://www.javacodegeeks.com/2013/02/pool-of-ssh-connections-using-apache-keyedobjectpool.html

您可以使用grep4j来使用此池 https://code.google.com/p/grep4j/source/browse/trunk/src/main/java/org/grep4j/core/command/linux/SessionFactory.java?r=354

还要确保您可以从执行计算机访问服务器。例如,如果目标服务器不在您的手中。它会抛出连接超时。

答案 2 :(得分:0)

我希望与您分享我们的实施情况,我们使用了Session Manager中的jsch-extension library

首先,您需要实现负责对象池生命周期的对象池工厂:

public class ChannelSftpConnectionsFactory extends BasePooledObjectFactory<ChannelSftp> {
    private SessionManager sessionManager;

    public ChannelSftpConnectionsFactory(final SessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    //Create and open channel
    @Override
    public ChannelSftp create() throws JSchException {
        ChannelSftp channelSftp = (ChannelSftp) sessionManager.getSession().openChannel("sftp");
        channelSftp.connect();

        return channelSftp;
    }

    //wrapping
    @Override
    public PooledObject<ChannelSftp> wrap(final ChannelSftp channelSftp) {
        return new DefaultPooledObject<>(channelSftp);
    }

    @Override
    //disconnect channel on destroy
    public void destroyObject(final PooledObject<ChannelSftp> pooledObject) {
        ChannelSftp sftp = pooledObject.getObject();
        disconnectChannel(sftp);
    }

    void disconnectChannel(final ChannelSftp sftp) {
        if (sftp.isConnected()) {
            sftp.disconnect();
        }
    }

    @Override
    //reset channel current folder to home if someone was walking on another folders
    public void passivateObject(final PooledObject<ChannelSftp> p) {
        ChannelSftp sftp = p.getObject();
        try {
            sftp.cd(sftp.getHome());
        } catch (SftpException ex) {
            log.error("Could not reset channel to home folder, closing it");
            disconnectChannel(sftp);
        }
    }

    @Override
    //validate object before it is borrowed from pool. If false object will be removed from pool
    public boolean validateObject(final PooledObject<ChannelSftp> p) {
        ChannelSftp sftp = p.getObject();
        return sftp.isConnected() && !sftp.isClosed();
    }
}

现在您可以使用配置的工厂创建池:

ObjectPool<ChannelSftp> createPool(final SessionManager sessionManager, final GenericObjectPoolConfig<ChannelSftp> poolConfig) {
    return PoolUtils.synchronizedPool(new GenericObjectPool<>(buildFactory(sessionManager), poolConfig));
}


PooledObjectFactory<ChannelSftp> buildFactory(final SessionManager sessionManager) {
    return PoolUtils.synchronizedPooledFactory(new ChannelSftpConnectionsFactory(sessionManager));
}

此Java文档将帮助您正确配置池:https://commons.apache.org/proper/commons-pool/api-2.6.0/org/apache/commons/pool2/impl/BaseGenericObjectPool.html

不要忘记正确借用对象并将对象归还给池:https://commons.apache.org/proper/commons-pool/api-2.6.0/org/apache/commons/pool2/ObjectPool.html