我有一个主主机(A),用于运行jar文件(a)。此jar文件使用Jsch库在三个主机(B,C,D)以及其他一些命令上运行jar文件(b,c,d)。
我当然想并行运行jar文件(b,c,d)。因此,我在jar文件(a)中使用了多线程策略。
由于执行(b,c,d)可能需要很长时间(几天),所以我想在主机(B,C,D)中执行(b,c,d)时关闭(a)中的ssh连接)。因此超时将不会发生。我该怎么办?
这是我的主主机代码(a):
MasterProcessing.java
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.sahab.omid.constants.Constants;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.Callable;
public class MasterProcessing implements Callable<Integer> {
public static Session session;
public static ChannelExec channel;
public int hostId;
MasterProcessing(int hostId_) {
hostId = hostId_;
}
public synchronized Integer call() {
String host = Constants.HOST_REMOTE.get(hostId);
String user = Constants.USER_REMOTE.get(hostId);
String password = Constants.PASSE_REMOTE.get(hostId);
System.out.println("Host with IP " + host + "(Thread: " + hostId + ") is starting...");
try {
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
// Create a JSch session to connect to the server
session = jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
// Establish the connection
session.connect();
System.out.println("Connected...");
executeCommand("mkdir /opt/myDir");
executeCommand("...");
executeCommand("...");
executeCommand("cd /opt/myDir && " + Constants.JAVA_HOME_MASTER + "/java -jar " + Constants.JAR_NAME_MASTER);
session.disconnect();
System.out.println("DONE!!!");
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public static void executeCommand(String command) throws JSchException, InterruptedException, IOException {
channel = (ChannelExec) session.openChannel("exec");
channel.setPty(true);
channel.setCommand(command);
channel.connect();
channel.run();
channel.setErrStream(System.err);
InputStream in = channel.getInputStream();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int j = in.read(tmp, 0, 1024);
if (j < 0) {
break;
}
System.out.print(new String(tmp, 0, j));
}
if (channel.isClosed()) {
if (channel.getExitStatus() > 0)
System.out.println("Exit Status: " + channel.getExitStatus());
break;
}
//Thread.sleep(100);
}
channel.disconnect();
}
}
这是运行线程的主要对象:
App.java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
MasterProcessing[] object = new MasterProcessing[Constants.HOSTS_NUM];
List<Future<Integer>> future = new ArrayList<>(Constants.HOSTS_NUM);
ExecutorService executorService = Executors.newFixedThreadPool(Constants.HOSTS_NUM);
//Constants.HOSTS_NUM is 3 (B, C, D)
for (int i = 0; i < Constants.HOSTS_NUM; ++i) {
object[i] = new MasterProcessing(i);
future.add(i, executorService.submit(object[i]));
Thread.sleep(1000);
}
List<Integer> hostsOutput = new ArrayList<>();
for (int i = 0; i < Constants.HOSTS_NUM; i++) {
hostsOutput.add(future.get(i).get());
}
System.exit(0);
}
}