Java 带执行器的JSch
我在使用Java 带执行器的JSch,java,executorservice,jsch,Java,Executorservice,Jsch,我在使用ExecutorService运行多个SSH作业(使用JSch)时遇到问题 当运行单个作业时,它们会按预期执行。但是,当我尝试运行多个作业时,只有第一个作业完全执行。我已将线程池更改为仅使用1个线程,认为这可能是端口问题,但仍然无法正常工作。任何帮助都将不胜感激 ExecutorService ex = Executors.newFixedThreadPool(4); Set<Future<Task>> set = new HashSet<Future<
ExecutorService
运行多个SSH作业(使用JSch)时遇到问题
当运行单个作业时,它们会按预期执行。但是,当我尝试运行多个作业时,只有第一个作业完全执行。我已将线程池更改为仅使用1个线程,认为这可能是端口问题,但仍然无法正常工作。任何帮助都将不胜感激
ExecutorService ex = Executors.newFixedThreadPool(4);
Set<Future<Task>> set = new HashSet<Future<Task>>();
for (int i = 0; i < tasks.size(); i++) {
Task task = tasks.get(i);
creds.setHostName(task.getFirewall().getAddress());
System.out.println("Task(" + i + ")=" + task);
Callable<Task> worker = new SSH.SSHWorker(creds, task, i);
ex.submit(worker);
}
ExecutorService ex=Executors.newFixedThreadPool(4);
Set=newhashset();
对于(int i=0;i
这是SSH
public class SSH {
LoginCredentials creds;
//ChannelExec channelExec;
ChannelExec channelExec;
BufferedReader consoleOutput;
Session session;
InputStream is;
UI ui;
String output = "";
// String command;
public boolean debug = false;
public SSH(LoginCredentials creds, String command) throws JSchException, IOException {
// System.out.println("NEW SSH");
this.creds = creds;
consoleOutput = new BufferedReader(new InputStreamReader(System.in));
ui = new UI();
this.connect();
Channel channel = session.openChannel("exec");
this.sendCommand(channel, command);
}
public String getOutput() {
return output;
}
public class UI extends MyUserInfo {
String message;
@Override
public void showMessage(String message) {
this.message = message;
super.showMessage(message); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getMessage() {
return this.message;
}
}
private void sendCommand(Channel channel, String command) throws IOException, JSchException {
this.channelExec = (ChannelExec) channel;
this.channelExec.setCommand(command);
//channel.setInputStream(null);
channel.setOutputStream(System.out);
this.is = channel.getInputStream();
channel.connect();
byte[] buffer = new byte[1024];
while (channel.getExitStatus() == -1) {
//System.out.println("Here 1.1");
while (is.available() > 0) {
//System.out.println("Here 1.2");
int i = is.read(buffer, 0, 1024);
//System.out.println("i= " + i);
if (i < 0) {
System.out.println("breaking");
break;
}
String string = new String(buffer, 0, i);
output = output.concat(string);
//System.out.println("output= "+output);
if (string.contains("Command authorization failed")) {
channel.disconnect();
break;
}
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
}
is.close();
channel.disconnect();
this.session.disconnect();
}
private void connect() throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(creds.getUser(), creds.getHostName(), 22);
session.setTimeout(0);
session.setPassword(creds.getPassword());
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setUserInfo(ui);
session.connect();
System.out.println("Connected in SSH");
}
public static class SSHWorker implements Callable {
private LoginCredentials lc;
private Task t;
private int thread;
public SSHWorker(LoginCredentials creds, Task task, int thread) {
this.t = task;
lc = creds;
this.thread = thread;
System.out.println("Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
}
@Override
public Task call() throws JSchException, IOException {
System.out.println("Doing Call For: Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
String enablepassword1 = (String) lc.getEnablePassword().get(0);
SSH ssh = new SSH(lc, t.getSSHCommand(enablepassword1));
this.t.setTaskResult(ssh.getOutput());
return t;
}
}
}
公共类SSH{
逻辑基础信条;
//ChannelExec ChannelExec;
ChannelExec ChannelExec;
缓冲读取控制台输出;
会议;
输入流为;
用户界面;
字符串输出=”;
//字符串命令;
公共布尔调试=false;
publicsh(logincredentialscreds,String命令)抛出jscheexception、IOException{
//System.out.println(“新SSH”);
this.creds=creds;
consoleOutput=新的BufferedReader(新的InputStreamReader(System.in));
ui=新ui();
这个.connect();
Channel=session.openChannel(“exec”);
此.sendCommand(通道,命令);
}
公共字符串getOutput(){
返回输出;
}
公共类UI扩展了MyUserInfo{
字符串消息;
@凌驾
公共void showMessage(字符串消息){
this.message=消息;
super.showMessage(message);//若要更改生成的方法体,请选择工具|模板。
}
@凌驾
公共字符串getMessage(){
返回此消息;
}
}
私有void sendCommand(Channel Channel,String命令)抛出IOException、jscheexception{
this.channelExec=(channelExec)通道;
此.channelExec.setCommand(命令);
//channel.setInputStream(空);
channel.setOutputStream(系统输出);
this.is=channel.getInputStream();
channel.connect();
字节[]缓冲区=新字节[1024];
而(channel.getExitStatus()=-1){
//System.out.println(“此处为1.1”);
while(is.available()>0){
//System.out.println(“此处为1.2”);
inti=is.read(缓冲区,0,1024);
//System.out.println(“i=“+i”);
if(i<0){
系统输出打印(“中断”);
打破
}
字符串=新字符串(缓冲区,0,i);
output=output.concat(字符串);
//System.out.println(“output=“+output”);
if(string.contains(“命令授权失败”)){
通道断开();
打破
}
}
if(channel.isClosed()){
System.out.println(“退出状态:+channel.getExitStatus());
打破
}
}
is.close();
通道断开();
this.session.disconnect();
}
私有void connect()抛出JSCHEException{
JSch JSch=新的JSch();
session=jsch.getSession(creds.getUser(),creds.getHostName(),22);
session.setTimeout(0);
session.setPassword(creds.getPassword());
属性配置=新属性();
配置放置(“检查”、“否”);
session.setConfig(config);
session.setUserInfo(ui);
session.connect();
System.out.println(“连接在SSH中”);
}
公共静态类SSHWorker实现可调用{
私人物流信用证;
私人任务t;
私有int线程;
公共SSHWorker(LoginCredentials、Task、int线程){
t=任务;
lc=信用;
this.thread=线程;
System.out.println(“Creds=“+lc.getHostName()+”Task=“+t+”Thread-”+Thread);
}
@凌驾
公共任务调用()抛出JSCHEException,IOException{
System.out.println(“Doing Call For:Creds=“+lc.getHostName()+”Task=“+t+”Thread-“+Thread”);
字符串enablepassword1=(字符串)lc.getEnablePassword().get(0);
SSH-SSH=newssh(lc,t.getSSHCommand(enablepassword1));
this.t.setTaskResult(ssh.getOutput());
返回t;
}
}
}
输出在此处(IP地址已更改)
在创建任务的循环中,您只使用一个
LoginCredentials
实例。因此,所有任务都共享该实例。在循环中,在每次迭代中覆盖主机名。因此,LoginCredentials
最终指的是上一个任务的主机名。因此,所有任务都连接到该主机
只是为了在创建JSch会话时不要通过LoginCredentials
传递主机名,而直接使用task.getFirewall().getAddress()
:
SSH-SSH=newssh(lc,t.getSSHCommand(enablepassword1),task.getFirewall().getAddress());
publicsh(LoginCredentials-creds、String命令、String主机名)
{
...
这个.connect(主机名);
}
...
私有void connect(字符串主机名)抛出JSCHEException{
JSch JSch=新的JSch();
session=jsch.getSession(creds.getUser(),主机名,22);
...
}
其他任务“未完全执行”是什么意思?有错误吗?异常?如果有2个任务,它将执行第一个任务2次。第二个永远不会。如果有4个任务,它将执行第一个任务4次,等等。我将更新我的代码并显示输出。我们甚至可以从您最初的问题中理解这一点吗?不管怎么说,问题仍然是unc