java连接远程服务器之manyged-ssh2 (windows和linux)
一、所需要的jar包
需要借助Ganymed SSH的jar包: ganymed-ssh2-262.jar
下载地址: http://www.ganymed.ethz.ch/ssh2/
API详情: http://www.ganymed.ethz.ch/ssh2/javadoc/ch/ethz/ssh2/package-summary.html
二、实现原理
Ganymed SSH-2 java在整个访问过程中担当SSH的客户端,由于Linux系统自带SSH服务,所以可以直接访问Linux系统并执行相关命令,而 Windows系统则需要首先安装SSH服务。
三、windows下ssh服务安装与配置
当远程服务器为Windows系统时, 需要在远程服务器中安装Windows版的SSH服务,比如:freesshd。
freesshd下载地址: http://www.freesshd.com/?ctt=download
freesshd安装与配置:(可以参考:http://www.cnblogs.com/xred/archive/2012/04/21/2461627.html)
1.安装完freesshd后,首选在[Users]下添加用来远程连接的win系统用户,此处采用密码认证的方式,允许使用shell:
2.然后再在【Authentication】下设置允许密码认证方式:
3.到[Server status]下查看SSH服务器状态,确保启动即可。最后点击【确定】即可。
四、java代码实现远程连接服务器并执行命令
1、接收执行命令返回pojo
1 package com.mu.mujup.governor.base.tomcatOper; 2 3 4 public class Result { 5 private String stdOut; 6 private String stdErr; 7 private int status; 8 public int getStatus() { 9 return status; 10 } 11 public void setStatus(int status) { 12 this.status = status; 13 } 14 public String getStdOut() { 15 return stdOut; 16 } 17 public void setStdOut(String stdOut) { 18 this.stdOut = stdOut; 19 } 20 public String getStdErr() { 21 return stdErr; 22 } 23 public void setStdErr(String stdErr) { 24 this.stdErr = stdErr; 25 } 26 }
2、给前台返回对象
1 package com.mu.mujup.governor.base.tomcatOper; 2 3 public class BackEntity { 4 5 private int status; 6 private String errMessage; 7 private String operator; 8 public int getStatus() { 9 return status; 10 } 11 public void setStatus(int status) { 12 this.status = status; 13 } 14 public String getOperator() { 15 return operator; 16 } 17 public void setOperator(String operator) { 18 this.operator = operator; 19 } 20 public String getErrMessage() { 21 return errMessage; 22 } 23 public void setErrMessage(String errMessage) { 24 this.errMessage = errMessage; 25 } 26 27 }
3、linux命令执行线程,这个线程执行linux命令并返回执行结果
1 package com.mu.mujup.governor.base.tomcatOper; 2 3 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 import ch.ethz.ssh2.Session; 8 9 10 /** 11 * @author jing.zhang 12 * @date 创建时间:2016年6月27日 上午8:52:02 13 * @version 1.0 14 * @description 15 */ 16 public class TomcatThread extends Thread{ 17 Object thread; 18 String cmds; 19 Session sess; 20 Result result; 21 private final String charset = "UTF-8"; 22 public TomcatThread(Object thread,String cmds,Session sess){ 23 this.thread = thread; 24 this.cmds = cmds; 25 this.sess = sess; 26 } 27 private void test(Object thread,String str){ 28 Result result = new Result(); 29 try{ 30 long start = System.currentTimeMillis(); 31 sess.execCommand(cmds); 32 System.out.println("时长是=="+(System.currentTimeMillis()-start)); 33 InputStream stdout = sess.getStdout(); 34 InputStream stderr = sess.getStderr(); 35 result.setStdOut(processStream(stdout, charset)); 36 result.setStdErr(processStream(stderr, charset)); 37 result.setStatus(sess.getState()); 38 this.result = result; 39 synchronized (thread) { 40 thread.notify(); 41 } 42 }catch(IOException e){ 43 this.result = null; 44 } 45 46 } 47 48 private String processStream(InputStream in, String charset) 49 throws IOException { 50 byte[] buf = new byte[1024]; 51 StringBuilder sb = new StringBuilder(); 52 while (in.read(buf) != -1) { 53 sb.append(new String(buf, charset)); 54 } 55 return sb.toString(); 56 } 57 58 public Result getRunback(){ 59 return this.result; 60 } 61 62 public void run() { 63 test(thread,cmds); 64 } 65 }
4、执行入口类(主线程),在方法exec处另起TomcatThread线程执行命令,并让主线程等待相应时间,主线程等待时间到了就结束子线程,
并用getRunback()获取子线程执行结果。如果超时返回为null。
1 package com.mu.mujup.governor.base.tomcatOper; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 import ch.ethz.ssh2.Connection; 7 import ch.ethz.ssh2.Session; 8 9 import com.eos.system.annotation.Bizlet; 10 11 12 /** 13 * 14 * @author jing.zhang 15 * @date 创建时间:2016年6月15日 下午4:31:16 16 * @version 1.0 17 * @description gonernor远程控制tomcat类 18 */ 19 20 @Bizlet("") 21 public class TomcatOperater { 22 // private String hostName; 23 // private String userName; 24 // private String password; 25 private final String charset = "UTF-8"; 26 27 private final String CHECK_TOMCAT_CMD = "curl -o /root/null -s -m 10 --connect-timeout 60 -w %{http_code} "; 28 29 public TomcatOperater() { 30 31 } 32 33 // public TomcatOperater(String hostName, String userName, String password) { 34 // this.hostName = hostName; 35 // this.userName = userName; 36 // this.password = password; 37 // } 38 39 /* 40 * 41 * @parameter 42 * @return 43 * @description 验证用户,是否接入服务器成功 44 */ 45 // private boolean login() throws IOException { 46 // conn = new Connection(hostName); 47 // conn.connect(); 48 // return conn.authenticateWithPassword(userName, password); 49 // } 50 51 /* 52 * 53 * @parameter 54 * @return 55 * @description 执行命令获得封装的Result对象 56 */ 57 private Result exec(Connection conn, String cmds ,long time) { 58 Result result = new Result(); 59 try { 60 Session sess = conn.openSession(); 61 // sess.execCommand(cmds); 62 // InputStream stdout = sess.getStdout(); 63 // InputStream stderr = sess.getStderr(); 64 // result.setStdOut(processStream(stdout, charset)); 65 // result.setStdErr(processStream(stderr, charset)); 66 // result.setStatus(sess.getState()); 67 68 TomcatThread test = new TomcatThread(this,cmds,sess); 69 test.start(); 70 synchronized (this) { 71 this.wait(time); 72 } 73 result = test.getRunback(); 74 test.interrupt(); 75 sess.close(); 76 } catch (Exception e) { 77 e.printStackTrace(); 78 } finally { 79 80 //conn.close(); 81 } 82 return result; 83 } 84 85 /* 86 * 87 * @parameter 88 * @return 89 * @description 检查tomcat状态 000-关闭 200-启动 90 */ 91 private boolean isStart(Connection conn, String hostName) 92 throws IOException { 93 String result = null; 94 InputStream in = null; 95 //'http://172.31.69.130:8080' 96 String url = "'http://" + hostName + ":8080'"; 97 String cmds = CHECK_TOMCAT_CMD + url; 98 Session session = conn.openSession(); 99 session.execCommand(cmds); 100 in = session.getStdout(); 101 result = processStream(in, charset).trim(); 102 session.close(); 103 return "200".equals(result) ? true : false; 104 } 105 106 /* 107 * 108 * @parameter 109 * @return 110 * @description 将流转化成字符串 111 */ 112 private String processStream(InputStream in, String charset) 113 throws IOException { 114 byte[] buf = new byte[1024]; 115 StringBuilder sb = new StringBuilder(); 116 while (in.read(buf) != -1) { 117 sb.append(new String(buf, charset)); 118 } 119 return sb.toString(); 120 } 121 122 @Bizlet("启动tomcat") 123 public BackEntity startTomcat(String osUsername ,String osPassword,String tmcStartBatch ,String ip,String adminPort) throws IOException { 124 BackEntity backEntity = new BackEntity(); 125 126 127 //测试开始 128 ip = "172.31.69.130"; 129 osUsername = "root"; 130 osPassword = "root123"; 131 adminPort = "8080"; 132 tmcStartBatch = "/root/apache-tomcat-7.0.69/bin/startup.sh"; 133 //测试结束 134 Connection conn = new Connection(ip); 135 conn.connect(); 136 boolean loginFlag = conn.authenticateWithPassword(osUsername, osPassword); 137 long time = 1000; 138 if (loginFlag) { 139 if (!isStart(conn, ip)) { 140 Result result = exec(conn, tmcStartBatch,time); 141 if(result!=null){ 142 if (result.getStdErr().trim().equals("")) { 143 backEntity.setErrMessage("success"); 144 } else { 145 backEntity.setErrMessage(result.getStdErr()); 146 } 147 }else{ 148 backEntity.setErrMessage("启动超时"); 149 } 150 } else { 151 backEntity.setErrMessage("success"); 152 } 153 } else { 154 backEntity.setErrMessage("服务器连接异常"); 155 } 156 conn.close(); 157 return backEntity; 158 } 159 160 @Bizlet("关闭tomcat") 161 public BackEntity stopTomcat(String osUsername ,String osPassword,String tmcStopBatch ,String ip,String adminPort) throws IOException { 162 BackEntity backEntity = new BackEntity(); 163 164 //测试开始 165 ip = "172.31.69.130"; 166 osUsername = "root"; 167 osPassword = "root123"; 168 adminPort = "8080"; 169 tmcStopBatch = "/root/apache-tomcat-7.0.69/bin/startup.sh"; 170 //测试结束 171 172 Connection conn = new Connection(ip); 173 conn.connect(); 174 boolean loginFlag = conn.authenticateWithPassword(osUsername, osPassword); 175 long time = 10000000;//脚本执行超时时间 176 if (loginFlag) { 177 if (!isStart(conn, ip)) { 178 Result result = exec(conn, tmcStopBatch,time); 179 if(result!=null){ 180 if (result.getStdErr().trim().equals("")) { 181 backEntity.setErrMessage("success"); 182 } else { 183 backEntity.setErrMessage(result.getStdErr()); 184 } 185 }else{ 186 backEntity.setErrMessage("关闭超时"); 187 } 188 } else { 189 backEntity.setErrMessage("success"); 190 } 191 } else { 192 backEntity.setErrMessage("服务器连接异常"); 193 } 194 conn.close(); 195 return backEntity; 196 } 197 198 @Bizlet("判断ip,用户名,密码,启动脚本是否为空") 199 public BackEntity validateNull(String osUsername ,String osPassword,String tmcStartBatch ,String ip,String adminPort) { 200 System.out.println("开始。。。。。。。。"); 201 BackEntity backEntity = new BackEntity(); 202 if(isNotEnputy(tmcStartBatch)&&isNotEnputy(ip)&&isNotEnputy(osPassword)&&isNotEnputy(osUsername)&&isNotEnputy(adminPort)){ 203 backEntity.setStatus(0); 204 }else{ 205 backEntity.setStatus(1); 206 } 207 return backEntity; 208 } 209 210 private boolean isNotEnputy(String str){ 211 if(str==null||str.equals("")){ 212 return false; 213 } 214 return true; 215 } 216 }