我是靠谱客的博主 鳗鱼发带,最近开发中收集的这篇文章主要介绍java 调用远程脚本_JAVA执行远端服务器的脚本,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题描述

工作中遇到这样一个问题,我们的应用为了实现高可用会采取双机部署,拓扑图大致如下:

66421e86f14fb131bc73144256fe4630.png

这种方案可以简单的保证高可用,即便应用服务器或者数据库服务器其中一台宕机,整个系统的功能还是不会受到影响,但是这里会出现一个问题:例如当应用服务器1宕机了,所有的负载集中到应用服务器2上以后,因为系统功能是正常的,而作为产品交付客户后也没有现场的实施或运维人员在,我们并不知道有一台服务器已经宕机了,所以,我们要实现一个简单的监控,去查看每个服务器上的每个应用程序是否正常的启动着,当异常的时候可以通过网页重新启动一下.

实现思路

在我们的数据库中建立两张表,一张服务器表,一张应用表,服务器表作为主表

在服务器对应位置为每一个需要监控的应用放置一个监控的SHELL脚本,一个重启的SHELL脚本

在WEB服务中增加定时任务,采用轮询的方式执行监控脚本,如果返回值正常,则更新应用表中的状态字段,同时在WEB页面中加入一个监控页面,可以在应用状态异常的通过按钮点击完成重启操作

技术要点

基本的增删改查并没有什么问题,在我的设计思路中有两个点需要注意

SHELL脚本的编写

这个领域我并不了解,交由负责实施的同事解决

JAVA任务调度

这部分我可能会单独写一篇博客来记录一下我自己学习Spring Boot中的 @Scheduled注解和比较常用的Quartz框架的过程和对比

JAVA链接服务器并执行SHELL

这里我采用的依赖包是:

ch.ethz.ganymed

ganymed-ssh2

262

在有了这个依赖包之后,我就只用提供两个共通的工具方法就可以了,一个是登录一下服务器,看看服务器是否宕机,一个是执行SELL脚本的方法,根据SHELL的返回值确定监控的服务是否正常的方法就好了

代码实现

因为执行SHELL脚本的时候可能是给出正常的返回值,也可能是异常的信息,这里需要一个JAVA Bean来接收这两个消息,代码如下:

import java.io.Serializable;

/**

* shell脚本执行结果

* 先通过getSuccess方法判断命令是否执行成功

* 执行成功的时候采用result作为返回值

* 执行不成功采用errorOut作为返回值

*

* @author weizj

*/

public class ShellResult implements Serializable {

private static final long serialVersionUID = -110281463872334425L;

/** 脚本输出结果 */

private String result;

/** 异常输出结果 */

private String errorMsg;

/** 回话退出状态 */

private int exitStatus;

public ShellResult() {

}

public ShellResult(String result, String errorOut, int exitStatus) {

this.result = result.trim();

this.errorMsg = errorOut.trim();

this.exitStatus = exitStatus;

}

public String getResult() {

return result;

}

public void setResult(String result) {

this.result = result.trim();

}

public String getErrorMsg() {

return errorMsg;

}

public void setErrorMsg(String errorMsg) {

this.errorMsg = errorMsg.trim();

}

public int getExitStatus() {

return exitStatus;

}

public void setExitStatus(int exitStatus) {

this.exitStatus = exitStatus;

}

/** 是否成功关闭会话 */

public boolean getSuccess() {

return this.exitStatus == 0;

}

}

工具类方法代码如下:

import java.io.IOException;

import java.io.InputStream;

import java.nio.charset.Charset;

import java.nio.charset.StandardCharsets;

/**

* java执行shell脚本的工具类

*

* @author weizj

*/

public class GanymedUtils {

private static final Logger logger = LoggerFactory.getLogger(GanymedUtils.class);

/** 超时时间 */

private static final int TIME_OUT = 1000 * 5 * 60;

/**

* 登录远端服务器

*

* @param ip 主机地址

* @param userName 用户名

* @param password 密码

* @return 当前的连接

* @throws IOException

*/

public static Connection login(String ip, String userName, String password) throws IOException {

Connection connection = new Connection(ip);

connection.connect();

return connection.authenticateWithPassword(userName, password) ? connection : null;

}

/**

* 执行一个命令

*

* @param ip 主机ip

* @param userName 用户名

* @param password 密码

* @param scripts 需要执行的脚本

* @param charset 字符编码

* @return ShellResult类

* @throws Exception

*/

public static ShellResult exec(String ip, String userName, String password, String scripts, Charset charset) throws IOException {

Connection connection = login(ip, userName, password);

if (connection == null) {

throw new RuntimeException("登录远程服务器出现异常,ip为:" + ip);

}

// Open a new {@link Session} on this connection

Session session = connection.openSession();

try (InputStream stdOut = new StreamGobbler(session.getStdout()); InputStream stdErr = new StreamGobbler(session.getStderr())) {

// Execute a command on the remote machine.

session.execCommand(scripts);

String outStr = processStream(stdOut, charset.name());

String outErr = processStream(stdErr, charset.name());

session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);

int exitStatus = session.getExitStatus();

return new ShellResult(outStr, outErr, exitStatus);

}

}

/**

* 执行脚本

*

* @param in 输入流

* @param charset 字符编码

* @return

* @throws IOException

*/

private static String processStream(InputStream in, String charset) throws IOException {

byte[] buf = new byte[1024];

StringBuilder sb = new StringBuilder();

while (in.read(buf) != -1) {

sb.append(new String(buf, charset));

}

return sb.toString();

}

public static void main(String[] args) {

try {

ShellResult status = exec("10.0.0.1", "root", "root", "ipconfig", StandardCharsets.UTF_8);

System.out.println(">>>>>>Result>>>>>>>");

System.out.println(status.getResult());

System.out.println(">>>>>>ErrorMsg>>>>>>>>");

System.out.println(status.getErrorMsg());

} catch (IOException e) {

e.printStackTrace();

}

}

}

通过这两个类再配合任务调度就可以基本的实现对应用的监控了.

最后

以上就是鳗鱼发带为你收集整理的java 调用远程脚本_JAVA执行远端服务器的脚本的全部内容,希望文章能够帮你解决java 调用远程脚本_JAVA执行远端服务器的脚本所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部