手写SSH2服务器连接池

2023-11-20

初衷:在工作中遇到一个要与远程服务器建立连接并进行上传、下载的场景,所以在课余就试着写了一个ssh2服务器连接池的小demo,仅供参考,欢迎指正~

目录概要

pom文件引入依赖

    <!--        使用ganymed-ssh2方式来连接SSH服务器-->
    <dependency>
      <groupId>ch.ethz.ganymed</groupId>
      <artifactId>ganymed-ssh2</artifactId>
      <version>262</version>
    </dependency>
编写连接对象实体类:
public class Ssh2Connection {
    Connection conn=null;//ssh2连接对象
    boolean isConn=false;//当前连接是否正在使用的标志,默认是没有使用
    //有参构造函数,根据一个ssh2的Connection构造一个当前的Ssh2Connection对象
    public Ssh2Connection(Connection connection){
        this.conn=connection;
    }
    //返回此对象中的连接
    public Connection getConnection(){
        return conn;
    }
    //设置此对象的连接
    public void setConnection(Connection connection){
        this.conn=connection;
    }
    //获取对象连接当前使用状态
    public boolean getIsConnection(){
        return isConn;
    }
    //设置对象连接当前正在使用
    public void setIsConnection(boolean isConn){
            this.isConn=isConn;
    }
}

自定义连接池规则接口,供调用:

//自定义连接池的规则
public interface ConnectionPools{
    int getInitConnections();//获取最初初始化的连接数
    void setInitConnections(int initConnections);//设置最初初始化的连接数
    int getIncrements();//获取每次增长的值
    void setIncrements(int increments);//设置每次增长的值
    int getMaxConnections();//获取最大连接数
    void setMaxConnections(int maxConnections);//设置最大连接数
    void initPool();//初始化连接池
    Connection getConnection();//获取连接
    void releaseConnection(Connection conn);//释放连接到连接池
    void refreshPool();//刷新连接池
    void closePool();//关闭连接池
    void narrowPools();//根据规则缩容连接池
}

读取配置文件信息:

package com.zm.core.config;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * Created by ZM on 2022/2/18 11:24
 */
public class GetParamsByProperties {//读取resources下ssh2.properties里面的配置信息

    //获取配置文件
    public static String readProperties(String param){
        String property="";
        try {
            Properties properties=new Properties();
            InputStream in = GetParamsByProperties.class.getResourceAsStream("/ssh2.properties");
            properties.load(in);
            property = properties.getProperty(param);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return property;
    }

}

配置文件ssh2.properties信息:


#远程主机参数
remote.ip=你的虚拟机ip地址#比如我的是192.168.147.130
remote.name=你的虚拟机用户名称
remote.password=你的虚拟机用户密码
remote.downloadPath=/home/zm/Downloads/
remote.uploadPath=/home/zm/Uploads/

#ssh2连接池参数
#连接池初始值大小
ssh2.initPoolSize=10
#连接池自增大小
ssh2.incrementSize=5
#最大连接数
ssh2.maxConnections=25
#获取一个可用连接的最大等待时间,毫秒
ssh2.maxWaitTimeByOneConnection=5000
#连接池缩小百分比,0~100,(当空闲连接数/连接池大小)达到该占比数值时,满足缩小连接池的规则。若填其它数字则按默认40进行
ssh2.idleRatio=40

编写实现类:

package com.zm.core;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import com.zm.core.bean.Ssh2Connection;
import com.zm.core.config.GetParamsByProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by ZM on 2022/2/17 14:02
 */
//连接池具体实现类
public class Ssh2ConnectionPools{
    private Logger logger= LoggerFactory.getLogger(Ssh2ConnectionPools.class);
    private String ip;
    private String name;
    private String password;

    private Integer initPoolSize=Integer.valueOf(GetParamsByProperties.readProperties("ssh2.initPoolSize"));
    private Integer incrementSize=Integer.valueOf(GetParamsByProperties.readProperties("ssh2.incrementSize"));
    private Integer maxConnections=Integer.valueOf(GetParamsByProperties.readProperties("ssh2.maxConnections"));
    private Integer maxWaitTimeByOneConnection=Integer.valueOf(GetParamsByProperties.readProperties("ssh2.maxWaitTimeByOneConnection"));
    private Integer idleRatio=Integer.valueOf(GetParamsByProperties.readProperties("ssh2.idleRatio"));
    private Vector connections=null;//存放连接池中ssh2连接的向量,初始为null
    private volatile static AtomicInteger freeNums;//计算空闲连接的个数


    public Ssh2ConnectionPools(String ip,String name,String password){
            this.ip=ip;
            this.name=name;
            this.password=password;
    }
//成员变量getter和setter
    //获取初始连接池大小
    public int getInitPoolSize(){
        return this.initPoolSize;
    }
    //设置初始连接池大小
    public void setInitPoolSize(int initPoolSize){
        this.initPoolSize=initPoolSize;
    }

    public int getIncrementSize() {
        return incrementSize;
    }

    public void setIncrementSize(int incrementSize) {
        this.incrementSize = incrementSize;
    }

    public int getMaxConnections() {
        return maxConnections;
    }

    public void setMaxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
    }

    //创建连接池
    public synchronized void createPool(){
        if (connections!=null){//如果连接池不为空则返回
            return;
        }
        //创建保存连接的向量,初始值为0个元素
        connections=new Vector();
        freeNums=new AtomicInteger(0);
        //根据连接池初始值大小创建连接
        createConnections(this.initPoolSize);
        logger.info("SSH2连接池初始化成功!");
    }

    private void createConnections(int initPoolSize){
        //循环创建指定数目的Ssh2连接
        for (int n=1;n<=initPoolSize;n++){
            if (this.maxConnections>0&&this.connections.size()>=this.maxConnections){
                //若当前创建的连接已经超过最大连接池初始数时
                return;
            }
            try {
                //新增一个连接到连接池向量中
                connections.addElement(new Ssh2Connection(newConnection()));
            } catch (IOException e) {
                logger.error("新建一个SSH服务器连接失败{}"+e.getMessage());
            }
        }
        if (this.connections==null){
            logger.info("SSH服务器连接池创建失败!");
        }else if (this.connections.size()<10){
            logger.info("SSH服务器连接池创建出错,已创建:"+this.connections.size()+"个连接");
        }else {
            logger.info("SSH服务器连接池创建新连接成功!");
        }

    }

    //创建一个新的连接
    private Connection newConnection() throws IOException {
        Connection connection=null;
        connection = new Connection(this.ip);
        connection.connect();
        if (!connection.authenticateWithPassword(this.name,this.password)){
            throw new RuntimeException("新建一个SSH服务器连接失败!");
        }
        freeNums.incrementAndGet();//空闲连接数加1
        logger.info("已创建一个新的SSH连接,空闲连接数为:"+freeNums.intValue());
        return connection;
    }

    //获得一个可用的连接
    public synchronized Connection getConnection() throws InterruptedException {
        //确保连接池已被创建
        if (connections==null){
            return null;
        }
        Connection conn=getFreeConnection();//获得一个可用的Ssh连接
        long start = System.currentTimeMillis();
        //假设目前没有可用的连接,则等待
        while (conn==null){
            logger.info("当前暂无可用SSH连接,请等待..");
            wait(250);//等待250毫秒
            conn=getFreeConnection();//重新获取一次
            if (System.currentTimeMillis()-start> maxWaitTimeByOneConnection){
                //如果获取一个可用连接等待超过5秒就打破返回null
                break;
            }
        }
        return conn;
    }

    //获取可用连接
    private Connection getFreeConnection() {
        //从连接池中获取一个可用连接
        Connection conn=findFreeConnection();
        if (conn==null){
            //如果当前连接池中没有可用的连接,则尝试新增一些连接
            createConnections(this.incrementSize);
            //重新检查是否有可用连接
            conn=findFreeConnection();
            if (conn==null){
                //如果依然没有可用连接,则返回null
                return null;
            }
        }
        return conn;
    }

    //检查是否有可用连接
    private Connection findFreeConnection() {
        Connection conn=null;
        Ssh2Connection ssh2Connection=null;
        //获取连接池向量中所有的对象
        Enumeration elements = connections.elements();
        //遍历所有对象,看看是否有可用对象
        while (elements.hasMoreElements()){
            ssh2Connection =(Ssh2Connection) elements.nextElement();
            if (!ssh2Connection.getIsConnection()){//如果有对象未被连接,则进行连接,并修改为已连接的状态
                conn=ssh2Connection.getConnection();
                ssh2Connection.setIsConnection(true);
                freeNums.decrementAndGet();//空闲连接数减一
                //测试该连接是否可用
                if (!tryConnection(conn)){
                    //如果该连接已不可用,则创建新的连接,替换旧的不可用的连接
                    try {
                        conn=newConnection();
                    } catch (IOException e) {
                        logger.error("在新建一个SSH服务器连接替换旧连接时,失败!");
                        return null;
                    }
                    ssh2Connection.setConnection(conn);
                }
                //测试可用,退出循环并返回该连接
                break;
            }
        }
        return conn;//返回可用连接
    }

    //测试当前连接是否可用
    private boolean tryConnection(Connection conn) {
            if (conn.isAuthenticationComplete()){
                // 如果至少有一个失败的身份验证请求并且最后一个失败的身份验证请求被服务器标记为“部分成功”,则返回 true。
                return true;
            }
            logger.info("当前SSH连接测试时不可用!");
            closeConnection(conn);//关闭连接并返回false
            return false;
    }

    //释放连接到连接池中
    public void releaseConnection(Connection conn){
            //先判断连接池是否存在
        if (this.connections==null){
            logger.error("SSH连接池不存在,无法将该连接释放回连接池!");
            return;
        }else if (conn==null){
            logger.error("待释放的SSH连接不为空!");
            return;
        }
        Ssh2Connection ssh2Connection=null;
        Enumeration elements = this.connections.elements();
        while (elements.hasMoreElements()){
            ssh2Connection=(Ssh2Connection) elements.nextElement();
            //现在连接池中找到要释放的连接对象
            if (conn==ssh2Connection.getConnection()){
                ssh2Connection.setIsConnection(false);
                //空闲连接数加1操作
                logger.info("已成功释放一个连接到SSH连接池中!当前连接池大小:"+this.connections.size()+",空闲连接数:"+freeNums.incrementAndGet());
                break;
            }
        }
        //narrowPools();
    }
    //刷新连接池
    public synchronized void refreshPool() throws InterruptedException, IOException {
        //确保连接池已存在
        if (this.connections==null){
            logger.error("SSH连接池不存在,无法刷新!");
            return;
        }
        Ssh2Connection ssh2Connection=null;
        Enumeration elements = this.connections.elements();
        while (elements.hasMoreElements()){//循环遍历所以连接对象
            ssh2Connection=(Ssh2Connection) elements.nextElement();
            if (ssh2Connection.getIsConnection()){//如果该连接忙,则等待一定时间
                wait(3000);//等待3秒
                //关闭此连接,用一个新的连接替换
                closeConnection(ssh2Connection.getConnection());
                ssh2Connection.setConnection(newConnection());
                ssh2Connection.setIsConnection(false);
                logger.info("已刷新替换一个忙碌的SSH连接");
            }
        }

    }
    //关闭连接
    private void closeConnection(Connection conn) {
        conn.close();
        freeNums.decrementAndGet();//连接数减一
        logger.info("已关闭并移除一个SSH连接");
    }

    //缩小连接池
    public synchronized void narrowPools(){//利用定时器定时执行,不再进行每当有连接释放成功后进行一次连接池的缩小
        //规则:空闲连接数占比连接池大小大于等于默认百分之40时,就符合缩小的规则,一直缩小到 占比小于等于4成 或者 连接池大小为初始连接池大小 为止
        if (this.connections==null){
            throw new RuntimeException("SSH连接池不存在,无法进行缩小!");
        }
        if (idleRatio>100||idleRatio<0){
            idleRatio=40;
        }
        if (this.connections.size()<=10||((freeNums.get()*100)/this.connections.size())<idleRatio){
            logger.info("SSH连接池容量正常,无需进行缩小...连接池:"+this.connections.size()+",空闲:"+freeNums.get()+"占比不超过百分之"+idleRatio);
            return;
        }
        Ssh2Connection ssh2Connection=null;
        Enumeration elements = this.connections.elements();
        while (elements.hasMoreElements()){
            ssh2Connection=(Ssh2Connection) elements.nextElement();
            if (!ssh2Connection.getIsConnection()&&this.connections.size()>10&&((freeNums.get()*100)/this.connections.size())>=idleRatio){
                closeConnection(ssh2Connection.getConnection());
                this.connections.removeElement(ssh2Connection);
            }
        }
        logger.info("缩小SSH连接池成功!当前连接池大小:"+this.connections.size()+",空闲连接数:"+freeNums.intValue());
    }

    //关闭连接池
    public synchronized void closePools() throws InterruptedException {
        //确保连接池存在
        if (this.connections==null){
            throw new RuntimeException("SSH连接池不存在,无法关闭!");
        }
        Ssh2Connection ssh2Connection=null;
        Enumeration elements = this.connections.elements();
        while (elements.hasMoreElements()){//循环遍历所以连接对象
            ssh2Connection=(Ssh2Connection) elements.nextElement();
            //如果该连接对象忙,则等待一定时间再删除
            if (ssh2Connection.getIsConnection()){
                //wait(5000);
            }
            closeConnection(ssh2Connection.getConnection());
            this.connections.removeElement(ssh2Connection);
            logger.info("正在关闭SSH连接:"+ssh2Connection);
        }
        this.connections=null;//连接池置为空
        logger.info("SSH连接池清空完毕!");
    }

}

连接池工具类,继承上面ConnectionPools的连接池接口,调用Ssh2ConnectionPools连接池实现类供外界使用

package com.zm.util;

import ch.ethz.ssh2.Connection;
import com.zm.core.ConnectionPools;
import com.zm.core.Ssh2ConnectionPools;
import com.zm.core.config.GetParamsByProperties;

import java.io.IOException;

/**
 * Created by ZM on 2022/2/18 10:12
 */
public class Ssh2Pool implements ConnectionPools {//懒汉式单例

     private static String ip= GetParamsByProperties.readProperties("remote.ip");
     private static String name=GetParamsByProperties.readProperties("remote.name");
     private static String password=GetParamsByProperties.readProperties("remote.password");

     private static boolean Ssh2PoolKey=false;//设置私有变量,除非获取这个名称,否则反射无法破坏单例
     private static Ssh2ConnectionPools connPools=null;
        //设置成单例模式,防止多次实例化连接池
        private Ssh2Pool(){//单例的关键是构造器私有
            synchronized (Ssh2Pool.class){
                if (Ssh2PoolKey==false){
                    Ssh2PoolKey=true;
                }else {
                    throw new RuntimeException("无需使用反射破坏单例");
                }
            }
        }
        private volatile static Ssh2Pool ssh2Pool;
        public static Ssh2Pool getInstance(){//单机下没事,多线程下会出错。所有这里要加双重检测锁模式才行,简称DCL懒汉式
            if (ssh2Pool==null){
                synchronized (Ssh2Pool.class){
                    if (ssh2Pool==null){
//new不是一个原子性操作,有三个步骤:1、分配内存空间;2、执行构造方法,初始化对象;3、把这个对象指向这个空间
//在多线程下,每个线程这3步的执行顺序可能不一样,就有可能造成出错,所以要禁止指令重排就得在定义lazyMan时加volatile!
                        ssh2Pool=new Ssh2Pool();
                    }
                }
            }
            return ssh2Pool;
        }
        static {
        connPools=new Ssh2ConnectionPools(ip,name,password);
        }

        @Override
        public int getInitConnections() {
            return connPools.getInitPoolSize();
        }

        @Override
        public void setInitConnections(int initConnections) {
            connPools.setInitPoolSize(initConnections);
        }

        @Override
        public int getIncrements() {
            return connPools.getIncrementSize();
        }

        @Override
        public void setIncrements(int increments) {
            connPools.setIncrementSize(increments);
        }

        @Override
        public int getMaxConnections() {
            return connPools.getMaxConnections();
        }

        @Override
        public void setMaxConnections(int maxConnections) {
            connPools.setMaxConnections(maxConnections);
        }

        @Override
        public void initPool() {
            connPools.createPool();
        }

        @Override
        public Connection getConnection() {
            Connection connection=null;
            try {
                connection= connPools.getConnection();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return connection;
        }

        @Override
        public void releaseConnection(Connection conn) {
            connPools.releaseConnection(conn);
        }

        @Override
        public void refreshPool() {
            try {
                connPools.refreshPool();
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void closePool() {
            try {
                connPools.closePools();
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
        }

    @Override
    public void narrowPools() {//缩小连接池
        connPools.narrowPools();
    }


}

项目启动看一下测试效果:

利用50个线程获取看看测试效果:

public class TestMain {  
  public static void main(String[] args) throws InterruptedException {
        Ssh2Pool pool=Ssh2Pool.getInstance();
        pool.initPool();
        TestMain testMain = new TestMain();
        testMain.test1(pool);

    }
private void test1(Ssh2Pool pool) throws InterruptedException {
        //String tempPath = null;
        try {
            for (int i = 1; i <=50; i++) {//使用50个线程去获取连接
                new Thread(()-> {
                        try {
                            System.out.println("线程"+Thread.currentThread().getName()+",开始获取连接...");
                            Connection conn=pool.getConnection();
                            Random random = new Random();
                            int t = random.nextInt(6);
                            //每个线程随机睡眠0~5秒
                            TimeUnit.SECONDS.sleep(t);
                            if (conn!=null){
                                pool.releaseConnection(conn);
                            }
                            TimeUnit.MILLISECONDS.sleep(t*100);//每个线程睡眠0到500毫秒后执行一次缩小连接池的操作
                            pool.narrowPools();//手动执行一次连接池的缩小操作
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
                },String.valueOf(i)).start();
                //获取连接connection后就可以进行操作了。。。
            }


        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            TimeUnit.SECONDS.sleep(30);
            pool.closePool();
        }

    }
}

后台日志信息:

21:20:54.187 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:1
21:20:54.292 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:2
21:20:54.421 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:3
21:20:54.547 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:4
21:20:54.657 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:5
21:20:54.779 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:6
21:20:54.894 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:7
21:20:55.005 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:8
21:20:55.142 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:9
21:20:55.248 [main] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:10
21:20:55.249 [main] INFO com.zm.core.Ssh2ConnectionPools - SSH服务器连接池创建新连接成功!
21:20:55.249 [main] INFO com.zm.core.Ssh2ConnectionPools - SSH2连接池初始化成功!
线程2,开始获取连接...
线程3,开始获取连接...
线程1,开始获取连接...
线程7,开始获取连接...
线程6,开始获取连接...
线程4,开始获取连接...
线程5,开始获取连接...
21:20:55.321 [5] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:4
21:20:55.322 [5] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:4占比不超过百分之40
线程8,开始获取连接...
线程9,开始获取连接...
21:20:55.322 [8] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:4
线程10,开始获取连接...
线程11,开始获取连接...
线程14,开始获取连接...
21:20:55.323 [8] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:3占比不超过百分之40
线程15,开始获取连接...
线程12,开始获取连接...
线程13,开始获取连接...
线程16,开始获取连接...
线程17,开始获取连接...
线程18,开始获取连接...
线程24,开始获取连接...
线程25,开始获取连接...
线程22,开始获取连接...
线程23,开始获取连接...
线程20,开始获取连接...
线程21,开始获取连接...
线程26,开始获取连接...
线程19,开始获取连接...
线程28,开始获取连接...
线程29,开始获取连接...
线程46,开始获取连接...
线程27,开始获取连接...
线程30,开始获取连接...
线程31,开始获取连接...
线程34,开始获取连接...
线程35,开始获取连接...
线程38,开始获取连接...
线程39,开始获取连接...
线程33,开始获取连接...
线程36,开始获取连接...
线程40,开始获取连接...
线程37,开始获取连接...
线程41,开始获取连接...
线程44,开始获取连接...
线程45,开始获取连接...
线程42,开始获取连接...
线程43,开始获取连接...
线程32,开始获取连接...
线程48,开始获取连接...
线程50,开始获取连接...
线程49,开始获取连接...
线程47,开始获取连接...
21:20:55.447 [15] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:1
21:20:55.567 [15] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:2
21:20:55.694 [15] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:3
21:20:55.810 [15] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:4
21:20:55.947 [15] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:5
21:20:55.947 [15] INFO com.zm.core.Ssh2ConnectionPools - SSH服务器连接池创建新连接成功!
21:20:55.947 [48] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:15,空闲连接数:1
21:20:56.117 [43] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:1
21:20:56.257 [43] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:2
21:20:56.321 [1] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:17,空闲连接数:3
21:20:56.323 [9] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:17,空闲连接数:4
21:20:56.412 [43] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:5
21:20:56.541 [43] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:6
21:20:56.678 [43] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:7
21:20:56.678 [43] INFO com.zm.core.Ssh2ConnectionPools - SSH服务器连接池创建新连接成功!
21:20:56.678 [43] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:20,空闲连接数:6
21:20:56.678 [42] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:20,空闲连接数:5
21:20:56.678 [43] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:20,空闲:4占比不超过百分之40
21:20:56.679 [37] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:20,空闲连接数:3
21:20:56.947 [49] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:20,空闲连接数:1
21:20:56.976 [38] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:2
21:20:57.282 [38] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:3
21:20:57.322 [4] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:22,空闲连接数:4
21:20:57.481 [38] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:5
21:20:57.673 [38] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:6
21:20:57.678 [44] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:24,空闲连接数:7
21:20:57.679 [36] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:24,空闲连接数:8
21:20:57.851 [38] INFO com.zm.core.Ssh2ConnectionPools - 已创建一个新的SSH连接,空闲连接数为:9
21:20:57.851 [38] INFO com.zm.core.Ssh2ConnectionPools - SSH服务器连接池创建新连接成功!
21:20:57.851 [35] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:7
21:20:57.852 [28] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:2
21:20:57.854 [21] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.854 [20] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [23] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [22] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [18] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.855 [17] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.856 [16] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.856 [13] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.856 [12] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:57.856 [28] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.857 [35] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.857 [36] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.857 [44] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.858 [4] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.858 [49] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.859 [37] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.859 [42] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.860 [9] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.860 [1] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.860 [48] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:57.947 [47] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:57.948 [50] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:2
21:20:58.105 [21] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:2
21:20:58.105 [21] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:2占比不超过百分之40
21:20:58.105 [20] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:58.105 [20] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:1占比不超过百分之40
21:20:58.106 [18] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.107 [12] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.107 [13] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.108 [17] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.108 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.108 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.108 [16] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.148 [47] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:58.148 [50] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:58.357 [18] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.357 [13] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.357 [12] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.359 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.359 [16] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.359 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.359 [17] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.607 [13] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.607 [12] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.607 [18] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.609 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.609 [17] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.609 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.609 [16] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.679 [39] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:58.679 [33] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:2
21:20:58.853 [29] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:3
21:20:58.858 [12] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:58.858 [12] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:1占比不超过百分之40
21:20:58.859 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.859 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.859 [17] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:58.879 [39] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:58.879 [33] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:58.947 [15] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:58.954 [29] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:1占比不超过百分之40
21:20:59.109 [24] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:59.109 [25] INFO com.zm.core.Ssh2ConnectionPools - 当前暂无可用SSH连接,请等待..
21:20:59.247 [15] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:0占比不超过百分之40
21:20:59.321 [7] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:2
21:20:59.321 [2] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:1
21:20:59.321 [3] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:3
21:20:59.323 [11] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:6
21:20:59.323 [14] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:4
21:20:59.323 [10] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:5
21:20:59.679 [45] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:5
21:20:59.722 [3] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.722 [7] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.722 [2] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.723 [14] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.723 [10] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.723 [11] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:20:59.979 [45] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:5占比不超过百分之40
21:21:00.106 [23] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:6
21:21:00.109 [17] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:7
21:21:00.209 [17] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:7占比不超过百分之40
21:21:00.306 [23] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:7占比不超过百分之40
21:21:00.321 [6] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:8
21:21:00.679 [41] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:9
21:21:00.822 [6] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:25,空闲:9占比不超过百分之40
21:21:00.852 [34] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:10
21:21:00.852 [30] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:11
21:21:00.852 [27] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:12
21:21:00.858 [13] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:13
21:21:00.948 [32] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:25,空闲连接数:14
21:21:01.060 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.060 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.061 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.061 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.062 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.062 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.064 [13] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.065 [13] INFO com.zm.core.Ssh2ConnectionPools - 缩小SSH连接池成功!当前连接池大小:18,空闲连接数:7
21:21:01.080 [41] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:18,空闲:7占比不超过百分之40
21:21:01.107 [22] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:18,空闲连接数:8
21:21:01.152 [34] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.152 [34] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:01.152 [34] INFO com.zm.core.Ssh2ConnectionPools - 缩小SSH连接池成功!当前连接池大小:16,空闲连接数:6
21:21:01.152 [27] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:16,空闲:6占比不超过百分之40
21:21:01.152 [30] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:16,空闲:6占比不超过百分之40
21:21:01.407 [22] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:16,空闲:6占比不超过百分之40
21:21:01.448 [32] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:16,空闲:6占比不超过百分之40
21:21:01.679 [40] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:7
21:21:01.851 [38] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:8
21:21:01.852 [46] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:9
21:21:01.855 [26] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:11
21:21:01.855 [19] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:10
21:21:01.858 [18] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:16,空闲连接数:12
21:21:02.158 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.159 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.159 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.159 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.161 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.163 [18] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:02.163 [18] INFO com.zm.core.Ssh2ConnectionPools - 缩小SSH连接池成功!当前连接池大小:10,空闲连接数:6
21:21:02.180 [40] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:6占比不超过百分之40
21:21:02.252 [38] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:6占比不超过百分之40
21:21:02.253 [46] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:6占比不超过百分之40
21:21:02.255 [19] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:6占比不超过百分之40
21:21:02.255 [26] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:6占比不超过百分之40
21:21:02.852 [31] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:7
21:21:02.859 [16] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:8
21:21:03.260 [16] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:8占比不超过百分之40
21:21:03.352 [31] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:8占比不超过百分之40
21:21:03.360 [25] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:9
21:21:03.760 [25] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:9占比不超过百分之40
21:21:04.359 [24] INFO com.zm.core.Ssh2ConnectionPools - 已成功释放一个连接到SSH连接池中!当前连接池大小:10,空闲连接数:10
21:21:04.859 [24] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池容量正常,无需进行缩小...连接池:10,空闲:10占比不超过百分之40
21:21:25.333 [main] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:25.333 [main] INFO com.zm.core.Ssh2ConnectionPools - 正在关闭SSH连接:com.zm.core.bean.Ssh2Connection@27ddd392
21:21:25.334 [main] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:25.334 [main] INFO com.zm.core.Ssh2ConnectionPools - 正在关闭SSH连接:com.zm.core.bean.Ssh2Connection@19e1023e
21:21:25.335 [main] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:25.335 [main] INFO com.zm.core.Ssh2ConnectionPools - 正在关闭SSH连接:com.zm.core.bean.Ssh2Connection@7cef4e59
21:21:25.335 [main] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:25.336 [main] INFO com.zm.core.Ssh2ConnectionPools - 正在关闭SSH连接:com.zm.core.bean.Ssh2Connection@64b8f8f4
21:21:25.336 [main] INFO com.zm.core.Ssh2ConnectionPools - 已关闭并移除一个SSH连接
21:21:25.336 [main] INFO com.zm.core.Ssh2ConnectionPools - 正在关闭SSH连接:com.zm.core.bean.Ssh2Connection@2db0f6b2
21:21:25.337 [main] INFO com.zm.core.Ssh2ConnectionPools - SSH连接池清空完毕!

Process finished with exit code 0

到这里,连接池的基本代码就已经编写完成,后面使用工具类去测试上传和下载,由于篇幅原因就不展示了,如果有兴趣的可以去看我的gitee仓库:

谢谢观看~Ssh2服务器连接池: 这是一个可以自定义参数的使用Ssh2连接远程服务器的连接池,比如目标服务器地址、名称和密码;自定义连接池参;还提供了两个工具类,来向目标服务器的指定路径下上传文件或下载文件icon-default.png?t=M276https://gitee.com/search-and-search/ssh-2-server-connection-pool

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手写SSH2服务器连接池 的相关文章

  • 如何使用Spring WebClient进行同步调用?

    Spring Framework in 休息模板 https docs spring io spring framework docs current javadoc api org springframework web client R
  • Java 7 默认语言环境

    我刚刚安装了 jre7 我很惊讶地发现我的默认区域设置现在是 en US 对于jre6 它是de CH 与jre7有什么不同 默认区域设置不再是操作系统之一吗 顺便说一句 我使用的是Windows7 谢谢你的回答 编辑 我已经看到了语言环境
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • HAProxy SSL终止+客户端证书验证+curl/java客户端

    我希望使用我自己的自签名证书在 HAProxy 上进行 SSL 终止 并使用我创建的客户端证书验证客户端访问 我通过以下方式创建服务器 也是 CA 证书 openssl genrsa out ca key 1024 openssl req
  • 埃拉托色尼筛法 - 实现返回一些非质数值?

    我用 Java 实现了埃拉托斯特尼筛法 通过伪代码 public static void sieveofEratosthenes int n boolean numArray numArray new boolean n for int i
  • 在 Struts 2 中传递 URL 参数而不使用查询字符串

    我想使用类似的 URL host ActionName 123 abc 而不是像这样传递查询字符串 host ActionName parm1 123 parm2 abc 我怎样才能在 Struts 2 中做到这一点 我按照下面的方法做了
  • 为自定义驱动程序创建 GraphicsDevice

    我正在开发一个在嵌入式系统中使用 Java 的项目 我有用于屏幕和触摸输入的驱动程序 以及用于文本输入的虚拟键盘 我的屏幕驱动程序有一个Graphics2D您可以绘制的对象和repaint Rectangle 更新方法 类似地 触摸驱动器能
  • 为什么Iterator接口没有add方法

    In IteratorSun 添加了remove 方法来删 除集合中最后访问的元素 为什么没有add方法来向集合中添加新元素 它可能对集合或迭代器产生什么样的副作用 好的 我们开始吧 设计常见问题解答中明确给出了答案 为什么不提供 Iter
  • 如何检测图像是否像素化

    之前有人在 SO 上提出过这样的问题 在Python中检测像素化图像 https stackoverflow com questions 12942365 detecting a pixelated image in python还有关于q
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • Java、Spring:使用 Mockito 测试 DAO 的 DataAccessException

    我正在尝试增加测试覆盖率 所以我想知道 您将如何测试 DAO 中抛出的 DataAccessExceptions 例如在一个简单的 findAll 方法中 该方法仅返回数据源中的所有数据 就我而言 我使用 Spring JdbcTempla
  • Spring Data JPA:查询如何返回非实体对象或对象列表?

    我在我的项目中使用 Spring Data JPA 我正在演奏数百万张唱片 我有一个要求 我必须获取各种表的数据并构建一个对象 然后将其绘制在 UI 上 现在如何实现我的 Spring 数据存储库 我读到它可以通过命名本机查询来实现 如果指
  • 无法在 Java/Apache HttpClient 中处理带有垂直/管道栏的 url

    例如 如果我想处理这个网址 post new HttpPost http testurl com lists lprocess action LoadList 401814 1 Java Apache 不允许我这么做 因为它说竖线 是非法的
  • Java - 从 XML 文件读取注释

    我必须从 XML 文件中提取注释 我找不到使用 JDOM 或其他东西来让它们使用的方法 目前我使用 Regex 和 FileReader 但我不认为这是正确的方法 您可以使用 JDOM 之类的东西从 XML 文件中获取注释吗 或者它仅限于元
  • 避免 Java 中的重复导入:继承导入?

    有没有办法 继承 导入 Example 常见枚举 public enum Constant ONE TWO THREE 使用此枚举的基类 public class Base protected void register Constant
  • 源值 1.5 的错误已过时,将在未来版本中删除

    我使用 scala maven plugin 来编译包含 scala 和 java 代码的项目 我已经将源和目标设置为1 7 但不知道为什么maven仍然使用1 5 这是我在 pom xml 中的插件
  • 何时在 hibernate 中使用 DiscriminatorValue 注解

    在 hibernate 中使用 DiscriminatorValue 注释的最佳场景是什么以及何时 这两个链接最能帮助我理解继承概念 http docs oracle com javaee 6 tutorial doc bnbqn html
  • Java 的 PriorityQueue 与最小堆有何不同?

    他们为什么命名PriorityQueue如果你不能插入优先级 它看起来与堆非常相似 有什么区别吗 如果没有区别那为什么叫它PriorityQueue而不是堆 默认的PriorityQueue是用Min Heap实现的 即栈顶元素是堆中最小的
  • 使用 JFreeChart 为两个系列设置不同的 y 轴

    我正在使用 JFreeChart 使用折线图绘制两个数据系列 XYSeries 复杂的因素是 其中一个数据系列的 y 值通常远高于第二个数据系列的 y 值 假设第一个系列的 y 值约为数百万数量级 而第二个数据系列的 y 值约为数百万数量级
  • ArrayList.clear() 和 ArrayList.removeAll() 有什么区别?

    假如说arraylist定义为ArrayList

随机推荐

  • Android4.0 SDK功能详解

    我在eoe的论坛找到的 就复制过来了 跟大家分享一下 Android 4 0 平台API等级 14 Android 4 0 是一次重要的平台发布版 为用户和应用程序开发者增加了大量的新特性 在下面我们将讨论的所有新特性和API中 因为它将
  • 【C++】C++11语法之右值引用

    文章目录 一 的扩展 initializer list的讲解 二 C 11一些小的更新 decltype nullptr 范围for 新容器 三 右值引用 右值真正的用法 完美转发 默认成员函数 总结 一 的扩展 在原先c 的基础上 C 1
  • 操作系统:进程学习笔记

    前言 程序顺序执行的三大特性 1 顺序性 指处理机严格按照程序所规定的的顺序执行 2 封闭性 指程序在封闭的环境运行即程序运行时独占全机资源 资源状态只能有本程序才能够改变它 程序一旦执行 其运行结果不受外界影响 3 可再现性 指只要程序执
  • 编写Shell脚本(批处理,一次执行多条命令)

    Bash终端的优势 1 上下键重复执行命令 2 tab键自动补齐 3 提供有用的环境变量 4 批处理 shell脚本文件建议以 sh为后缀 其实vim创建文本文件时 对名字无要求 但最好规定格式 echo SHELL 输出为 bin bas
  • grep的用法

    命令介绍 Linux系统中grep命令是一种强大的文本搜索工具 它能使用正则表达式搜索文本 并把匹配的行打印出来 匹配到的标红grep全称是Global Regular Expression Print 表示全局正则表达式版本 它的使用权限
  • khv是什么虚拟服务器,服务器虚拟化vSphere4 vs Hyper-V R2,选择谁?

    目前在X86服务器平台上做虚拟化 是非常热的 目前主要有两个选择 VMWare的vSphere4和微软的Hyper V R2 VMWare非常成熟 企业级用户很多 但价格不便宜 按照CPU数量和版本收费 Hyper V R2很便宜 但出来的
  • 检查内存泄露

    自己编写的视频处理程序出现了一个问题 每帧的运行时间随着运行时间在不断增长 很大可能是出现了内存泄露 于是学习了一些查看内存泄露的方法 做了两种尝试 一是VS自带的DEBUG下的检测 view pl html view plain copy
  • Windows上让Qt5 QCamera响应UVC摄像头硬件按钮拍图

    QCamera相机类提供了一些基本的功能 包括拍照和录制功能 Windows上不支持录制视频 但也有很多接口是没有封装的 比如有些UVC摄像头有物理按键 可以进行拍图等操作 但是QCamera没法响应硬件按钮的拍图操作 网络上的相关代码都是
  • RC-u4 相对论大师(bfs求解指定路径)

    PTA 程序设计类实验辅助教学平台 题解 bfs可以求解从根节点到叶子节点的指定路径 这里的vis 不是为了防止访问到父节点 更多的是为了缩小路径长度 mpp和mp的映射也很巧妙 开始我用的还是map
  • [从零开始学习FPGA编程-38]:进阶篇 -语法-函数与任务

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 第1章 什么是函数Function 1 1 什么是函数 1 2 函
  • 【JAVA】输入:Scaner

    一 语法 1 导入 import java util Scanner 2 创建对象 Scanner scanner new Scanner System in 3 创建变量 int x scanner nextInt next系列 next
  • 服务器运维基础指南

    服务器运维基础指南 作为一个开发人员 对于服务器的操作不可避免 最常用的操作就是部署应用到服务器 及在生产 测试环境通过查看日志排查问题 一般服务器都是linux操作系统并且是无图形界面的 所以进行任何操作都是通过命令行 由于从新一代程序员
  • Android 中的AIDL 和 binder机制

    一 Binder 1 线程间通信Handler Handler和Binder是Android通信的两大支柱 Handler是线程间通信的基础 一个App的运行一定是多个线程相互协作的过程 特别是Android子线程不能更新UI界面的限制使得
  • 微信使用精准位置 wx.getLocation步骤

    微信小程序 gt 开发设置 gt 接口设置 gt 开通 wx getLocation 申请理由 应当前业务涉及周边服务推荐需要 需获取用户地理位置信息 调试基础库 2 24 4 在app json中添加 requiredPrivateInf
  • VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题...

    VC9编译的程序在没有装过VC9 确切的说是 Net Framework3 5 的机器上运行时 如果提示 由于应用程序配置不正确 应用程序未能启动 重新安装应用程序可能会纠正这个问题 这个错误 那么就说明该程序动态链接了VC9的运行时库 如
  • Java 实现 SCP 携带密码拷贝文件

    package com miracle luna scp import org apache sshd client SshClient import org apache sshd client session ClientSession
  • 线上阿里云短信盗刷问题实录

    背景 营销系统中有定时任务处理将待支付订单变更为已取消 执行时间五分钟一次 业务执行处理异常会发送短信给相关开发人员进行短信提醒 从下午一点二十五开始 开发人员间隔五分钟就会收到业务执行异常的短信提醒 最初因为测试或是正式环境中确实有异常的
  • 国产化系统下操作PDF

    本文围绕使用netcore 跨平台在国产系统 麒麟和统信 操作PDF 首先netcore 需要第三方dll 在Nuget里搜索itextsharp 选择图片中 安装即可 版本写了 itextsharp 是4 16 比较靠后 但是基本功能都有
  • Android反调试方法总结以及源码实现之检测篇(一)

    好久没有更新博客了 主要是忙项目的事 今日总结一下在Android中常遇到的反调试方法 一来帮助需要之人 二来加深自己的理解 反调试在代码保护中扮演着很重要的角色 虽然不能完全阻止攻击者 但是还是能加大攻击者的时间成本 一般与加壳结合使用
  • 手写SSH2服务器连接池

    初衷 在工作中遇到一个要与远程服务器建立连接并进行上传 下载的场景 所以在课余就试着写了一个ssh2服务器连接池的小demo 仅供参考 欢迎指正 目录概要 pom文件引入依赖