您的位置:首页 > 运维架构 > Linux

利用JSCH实现远程操作Linux系统和hadoop集群

2016-06-06 10:54 866 查看
问题描述:在java web项目中要实现远程对hadoop集群的监控和管理,需要发送相关hadoop命令到集群,并得到相应结果。
解决办法:利用jsch插件。
首先我们先来认识一下jsch:

JSch 是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。你可以将它的功能集成到你自己的 程序中。同时该项目也提供一个J2ME版本用来在手机上直连SSHD服务器。它实际上就是一个ssh的远程登录,我们可以利用jsch来向某一个系统传递命令,这一优良特性可以让我们完成很多事情。

下面介绍一下jsch的实现:
它的实现十分简单,一个Jar包,两个方法。下面给出代码示例:
依赖jar包:jsch-0.1.53.jar

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class ShellServiceImpl{
private static JSch jsch;
private static Session session;

/**
* 连接到指定的IP
*
* @throws JSchException
*/
public  void connect(String user, String passwd, String host) throws JSchException {
jsch = new JSch();
session = jsch.getSession(user,host,22); //默认端口为22
session.setPassword(passwd);

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

session.connect();
}

/**
* 执行相关的命令
* @throws JSchException
*/

public StringBuffer execCmd(String command, String user, String passwd, String host) throws JSchException {
System.out.println(host);
connect(user, passwd, host);   //远程登录
System.out.println("After Connect!");
BufferedReader reader = null;
Channel channel = null;
try {
if (command != null) {
channel = session.openChannel("exec");
System.out.println(command);
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
channel.connect();
InputStream in = channel.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
String buf = null;
StringBuffer info = new StringBuffer("");
while ((buf = reader.readLine()) != null) {
info.append("\n");
info = info.append(buf);
}
System.out.println(info);
return info;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
channel.disconnect();
session.disconnect();
}
return null;
}
public static void main(String[] args) throws JSchException{
ShellServiceImpl test=new ShellServiceImpl();
test.execCmd("ifconfig", "user", "***.***.***.***(host)", "password");

}
}


我们用到 这项技术可以向hadoop集群发送命令,例如:"hadoop fs -ls /",查看HDFS文件系统。但是在这里我遇到了一些问题,在执行命令时,命令行提示:bash:hadoop:Command not found。

当我测试了其他命令时,例如系统命令“ifconfig”,java命令“java -version”,均提示command not found。但是这些命令在本地命令行执行都是可以的。这令我很费解,因为提示命令找不到一定是环境变量配置的问题,但是我的/etc/profile里面都正确配置了环境变量。而且如果环境变量真的配置有误的话我在本地是不能执行这些命令的。
之后我上网找了相关资料,网上有关环境变量是这么写的:
/etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc很容易混淆,他们之间有什么区别?它们的作用到底是什么?
/etc/profile: 用来设置系统环境参数,比如$PATH.
这里面的环境变量是对系统内所有用户生效的。
/etc/bashrc:  这个文件设置系统bash shell相关的东西,对系统内所有用户生效。只要用户运行bash命令,那么这里面的东西就在起作用。
~/.bash_profile: 用来设置一些环境变量,功能和/etc/profile 类似,但是这个是针对用户来设定的,也就是说,你在/home/user1/.bash_profile 中设定了环境变量,那么这个环境变量只针对 user1 这个用户生效.
~/.bashrc: 作用类似于/etc/bashrc, 只是针对用户自己而言,不对其他用户生效。
另外/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系.
~/.bash_profile 是交互式、login 方式进入 bash 运行的,意思是只有用户登录时才会生效。
~/.bashrc 是交互式 non-login 方式进入 bash 运行的,用户不一定登录,只要以该用户身份运行命令行就会读取该文件。

 这里我们可以看到,/etc/profile和~./bashrc_profile是等价的,/etc/bashrc和~/.bashrc是等价的,区别只是针对的用户范围不同,前者是针对所有用户的,而后者是针对单个用户的。这里重点注意一句话:“/etc/bashrc:  这个文件设置系统bash shell相关的东西,对系统内所有用户生效。只要用户运行bash命令,那么这里面的东西就在起作用。”我们刚才提示的问题就是bash命令找不到,现在我们在/etc/bashrc内重新配置所需命令的环境变量,source
/etc/bashrc使配置生效,再次执行上面的程序,就能看到相应命令的正确的返回结果了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息