web-dev-qa-db-ja.com

JSchセッションのタイムアウト制限

JSch 0.1.50を使用して、CI Jenkinsプラグイン用のリモートサーバーへの接続を設定しています。ここでsession.connect(60000);をタイムアウト60秒間使用しようとしていると仮定します。

Session session = null;
try {
    JSch jsch = new JSch();
    if (rsaIdentity != null && !rsaIdentity.equals("")) {
        jsch.addIdentity(rsaIdentity.trim());
    }
    session = jsch.getSession(serverLogin, serverHost, Integer.parseInt(serverPort));
    session.setPassword(getDescriptor().getOpenPassword(encryptedPasswordString));
    session.setConfig("StrictHostKeyChecking", "no"); // not use RSA key

    int timeOut = Integer.parseInt(getDescriptor().getConnectionTimeOut());

    session.connect(60000);

} catch (SocketTimeoutException e) {
    logger.error(e.getMessage());
    return false;
} catch (JSchException e) {
    logger.error(e.getMessage());
    return false;
}

しかし、実際には、接続中のこのコードの実行中にサーバーがかなり低速になると、毎回約20秒でタイムアウトExceptionに直面します。

2016-01-25 13:15:55.982 [INFO] Connecting to server: devsrv26:22 as [user] ...
2016-01-25 13:16:16.991 [ERROR] Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992 com.jcraft.jsch.JSchException: Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992     at com.jcraft.jsch.Util.createSocket(Util.Java:389)
2016-01-25 13:16:16.993     at com.jcraft.jsch.Session.connect(Session.Java:215)
2016-01-25 13:16:16.993     at com.mycomp.jenkins.MyPlugin.perform(MyPlugin.Java:225)

76991-55982 = 21008ミリ秒

この20秒のタイムアウトの理由は誰か知っていますか?

9

_Util.createSocket_の実装方法を確認すると、timeoutが基になるtimeoutに奇妙に渡されていないため、Socketは接続の上限のみを定義し、下限は定義していないことがわかります。

これらの20秒は、おそらくOSレベルのデフォルト制限です。

これをオーバーライドするには、 SocketFactory を実装して、 _Session.setSocketFactory_ を使用してセッションにアタッチします。

工場では Socket.connect(SocketAddress endpoint, int timeout) を使用します。

何かのようなもの:

_public class SocketFactoryWithTimeout implements SocketFactory {
  public Socket createSocket(String Host, int port) throws IOException,
                                                           UnknownHostException
  {
    socket=new Socket();
    int timeout = 60000;
    socket.connect(new InetSocketAddress(Host, port), timeout);
    return socket;
  }

  public InputStream getInputStream(Socket socket) throws IOException
  {
    return socket.getInputStream();
  }

  public OutputStream getOutputStream(Socket socket) throws IOException
  {
    return socket.getOutputStream();
  }
}
_
2
Martin Prikryl