最近写了一个docker微服务,此微服务需要在晚上12点时远程触发hadoop集群的一个hive离线计算任务,因此需要 远程调用linux shell
于是用到了ganymed-ssh2 这个库
Maven里的依赖如下:
<dependencies> <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>build210</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies>
测试代码如下:
package sshtest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import ch.ethz.ssh2.ChannelCondition; import ch.ethz.ssh2.Connection; import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; public class RemoteExecuteCommand { // 字符编码默认是utf-8 private static String DEFAULTCHART = "UTF-8"; private Connection conn; private String ip; private String userName; private String userPwd; public RemoteExecuteCommand() { this.ip = "172.27.8.132"; this.userName = "root"; this.userPwd = "123456"; } public Boolean login() { boolean flg = false; try { conn = new Connection(ip); conn.connect(); flg = conn.authenticateWithPassword(userName, userPwd); } catch (IOException e) { e.printStackTrace(); } return flg; } public String execute(String cmd) { String result = ""; try { if (login()) { System.out.println("hihiihihih2222:"); Session session = conn.openSession(); session.requestPTY("bash"); session.startShell(); PrintWriter out = new PrintWriter(session.getStdin()); out.println(cmd); out.flush(); out.println("exit"); out.close(); session.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, 60000); System.out.println("exec has finished!"); session.close(); conn.close(); } } catch ( IOException e) { e.printStackTrace(); } return result; } }
package sshtest;
public class SshTest { public static void main(String[] args) { RemoteExecuteCommand rec = new RemoteExecuteCommand(); String result = rec.execute("sh /home/mongo-hive-hbase/Hive_HistClientsInfoAnalysis.sh");return; } }
参考:
http://www.cnblogs.com/-wangjiannan/p/3751330.html
http://www.programcreek.com/
BTW,用此库调用shell脚本时,因为微服务不需要一直挂着等脚本,因此,需要用nohup的方式来让shell脚本后台执行,这样即使终端关闭也不会对执行有影响。
由于是docker服务,在布署docker的时候会起两个docker 同时起,导致到了12点会触发执行两次shell脚本,这个问题定位了两天。。。。本地windows 下Eclipse试
着去触发都好好的,布署到docker上就是会触发两次,于是,怀疑
1.ganymed ssh2库接口的使用问题, 从session.execCommand(cmd) 这种调用方式换成了
session.requestPTY("bash");
session.startShell();
这种方式,还是一样。
2. 怀疑windows /linux环境的不同所导致 , 结果用以上sshtest的测试程序放在本地linux机器上试仍然ok
3. 怀疑是docker环境的问题,把以上sshtest打包成docker,在本地手动执行(本地环境只会起一个docker),继续ok
4.怀疑人生。。。。。
5. 最后绝望之前猛然发现docker get pods -o wide |grep xxx,发现有两个在执行,把这事儿给忘记了。。
不过总归是搞定了