JSch: How to keep the session alive and up

送分小仙女□ 提交于 2019-11-28 06:33:01
blafasel

After trying Session.sendKeepAliveMsg() without success, I came to the following solution which seems to be rather stable:

private Session getSession() throws Exception {
    try {
        if (!session.isConnected()) {
            logger.info("Session successfully tested, use it again.");
            session.connect();
        }
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        session = jsch.getSession(user, host, port);
        session.setConfig(config);
        session.connect();
    }
    return session;
}

Update: Some days later it failed.

I tried to test it by killing the open session on the server. All prior versions I tested this way showed the exact same behavior, regardless whether the problem popped up after waiting some days or killing the server process, so I thought this test - and its outcome for the above solution - to be meaningful. Unfortunately, it isn't.

I'm going to try some other ways to fix it and keep you up to date.

Update 2: Final solution, guaranteed inelegant and working:

private Session getSession() throws Exception {
    try {
        ChannelExec testChannel = (ChannelExec) session.openChannel("exec");
        testChannel.setCommand("true");
        testChannel.connect();
        if(logger.isDebugEnabled()) {
            logger.debug("Session successfully tested, use it again.");
        }
        testChannel.exit();
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        session = jsch.getSession(user, host, port);
        session.setConfig(config);
        session.connect();
    }
    return session;
}

This version runs several weeks in a productive environment. Once a day I have the info message logged.

The costs of opening a channel and performing some do-nothing-command are somewhat annoying, but I found no other way to be definitely sure about the state of the session.

You can try by invoking the following method before invoking Session#connect().

Session#setServerAliveInterval(int milliseconds)

Although I found one more function Session#sendKeepAliveMsg() which can be tried.

You can use a pool , I used org.apache.commons.pool2 so the pool is responsible of providing connected sessions, basically:

  • Create JSCH Session on makeObject
  • connect on activate if disconnected
  • check if isConnected on validate
  • sendKeepAliveMsg on passivate

Above worked for me, also keep in mind that if you add logic on validate, the poolConfig should set true on testOnBorrow or testOnReturn. So I used KeyedObjectPool you should get connections from the pool via borrowObject method and make sure you return them to the pool once you operation is complete via returnObject.

https://commons.apache.org/proper/commons-pool/api-2.2/org/apache/commons/pool2/PooledObjectFactory.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!