即使远程服务器上的脚本完成任务,Java应用程序也会挂起很长时间

时间:2015-01-08 15:37:42

标签: java client-server jsch

提前感谢您的支持。

我在我的java应用程序中使用JSCH来调用远程服务器(Red Hat OS)上的exe文件。我注意到,即使exe完成了它的工作,我的java应用程序也会挂起很长时间。

远程服务器上的exe文件执行时间超过20分钟,因为它需要处理大量文本文件。

在另一种情况下,如果我使用一个小的输入文件并且exe执行一分钟,则java应用程序不会挂起。

请告知申请暂停的原因。我是否需要在jsch代码中添加一些设置?

这是代码,

JSch jsch=null;
    Session session=null;
    java.util.Properties config=null;
    ChannelSftp sftpChannel=null;
    Channel channel=null;
    InputStream in=null,error=null;

    try
    {
        jsch=new JSch();
        session=jsch.getSession(USERNAME, IP, PORT);
        session.setPassword(PASSWORD);

        logBasic("Node="+NODE_ID+", Host IP="+IP+", Port="+PORT+",Username="+USERNAME+", Dump Command="+MIG_TOOL_COMMAND+", Remote Path="+MIG_TOOL_PATH+"\n");  
        scriptOutput.append("Node="+NODE_ID+", Host IP="+IP+", Port="+PORT+",Username="+USERNAME+", Dump Command="+MIG_TOOL_COMMAND+", Remote Path="+MIG_TOOL_PATH+"\n");   
        FILE_NAME=KETTLE_HOME+"/"+LOGS_DIR+"/"+NODE_ID+"_master_slave_execution.log";

        config = new java.util.Properties(); 
        config.put("StrictHostKeyChecking", "no");
        session.setConfig("PreferredAuthentications", 
                      "password");

        session.setConfig(config);
        session.setServerAliveInterval(60*60*60*1000);
        session.connect();

        channel=session.openChannel("exec");
        //((ChannelExec)channel).setCommand(JAVA_COMMAND);
        logBasic("Command = cd "+ MIG_TOOL_PATH+" && "+JAVA_COMMAND+" && "+MIG_TOOL_PATH+MIG_TOOL_COMMAND+" WORKING_MODE="+SLAVE_WORKING_MODE+" INPUT_FILE="+SDP_INPUT_FILENAME+".gz STAND_ALONE_FLAG="+STAND_ALONE_FLAG);
        ((ChannelExec)channel).setCommand("cd "+ MIG_TOOL_PATH+" && "+JAVA_COMMAND+" && "+MIG_TOOL_PATH+MIG_TOOL_COMMAND+" WORKING_MODE="+SLAVE_WORKING_MODE+" INPUT_FILE="+SDP_INPUT_FILENAME+".gz STAND_ALONE_FLAG="+STAND_ALONE_FLAG);

        in=channel.getInputStream();
        error=((ChannelExec)channel).getErrStream();
        channel.connect();


        scriptOutput.append("Error Ouput:\n");

        byte[] tmp=new byte[1024];

        boolean flag=true;
        while(flag)
        {
            while(error.available()>0)
            {
                int i=error.read(tmp, 0, 1024);
                if(i<0) break;
                scriptOutput.append(new String(tmp, 0, i));
            }
            if(channel.isClosed()) flag=false;
            try
            {
                Thread.sleep(threadSleepTime);
            }
            catch(Exception exception)
            {
                logError(exception.getMessage(), exception);
            }
        }

        scriptOutput.append("Log Ouput:\n");

        flag=true;

        while(flag)
        {
            while(in.available()>0)
            {
                int i=in.read(tmp, 0, 1024);
                if(i<0) break;
                scriptOutput.append(new String(tmp, 0, i));
            }
            if(channel.isClosed()) flag=false;
            try
            {
                Thread.sleep(threadSleepTime);
            }
            catch(Exception exception)
            {
                logError(exception.getMessage(), exception);
            }
        }

        channel.disconnect();
        channel=null;

        session.disconnect();

1 个答案:

答案 0 :(得分:2)

我尝试了我在评论中所说的内容并且工作正常 如果您的超时时间少于100秒,请调整setServerAliveInterval(100),如果您需要超过9999 x 100s,请修改setServerAliveCountMax(9999)

如果这不起作用,请检查服务器端的sshd_config文件,看看是否有任何设置不允许您保持连接活动。

Java:

JSch jsch;
Session session;
Properties config;
Channel channel;
InputStream in, error;
long threadSleepTime = 100;

try {
  jsch = new JSch();
  session = jsch.getSession("timeoutuser", "timeoutHost", 22);
  session.setPassword("pTimeout");

  config = new Properties();
  config.put("StrictHostKeyChecking", "no");
  session.setConfig("PreferredAuthentications", "password");

  session.setConfig(config);
  session.setServerAliveInterval(100);// Send null packet each 100s
  session.setServerAliveCountMax(9999);// Send 9999 max null packet
  session.connect(0);// No connection timeout

  channel = session.openChannel("exec");
  ((ChannelExec) channel).setCommand("./wait.sh");

  in = channel.getInputStream();
  error = ((ChannelExec) channel).getErrStream();
  channel.connect();
  byte[] tmp = new byte[1024];

  boolean flag = true;
  while (flag) {
    while (error.available() > 0) {
      int i = error.read(tmp, 0, 1024);
      if (i < 0) {
        break;
      }
      System.out.print(new String(tmp, 0, i));
    }

    if (channel.isClosed()) {
      flag = false;
    }

    try {
      Thread.sleep(threadSleepTime);
    } catch (InterruptedException ex) {
      System.err.println(ex.getMessage());
    }
  }

  System.out.print("\nLog Ouput:\n");

  flag = true;

  while (flag) {
    while (in.available() > 0) {
      int i = in.read(tmp, 0, 1024);
      if (i < 0) {
        break;
      }
      System.out.print(new String(tmp, 0, i));
    }

    if (channel.isClosed()) {
      flag = false;
    }

    try {
      Thread.sleep(threadSleepTime);
    } catch (InterruptedException ex) {
      System.err.println(ex.getMessage());
    }
  }

  channel.disconnect();

  session.disconnect();
} catch (JSchException | IOException ex) {
  System.err.println(ex.getMessage());
}

脚本wait.sh

#!/bin/bash

for i in {1..20}
do
  sleep 2m
  if [ $((RANDOM%5)) -gt 3 ]; then
    echo "Error $i in process" 1>&2
  fi
done
echo "Process done"

输出:

run:
Error 2 in process
Error 6 in process
Error 12 in process
Error 13 in process
Error 19 in process
Error 20 in process

Log Ouput:
Process done
BUILD SUCCESSFUL (total time: 40 minutes 0 seconds)