【Spring boot配置模板】java远程执行shell命令(支持向多主机发起远程命令)

【Spring boot配置模板】java远程执行shell命令(支持向多主机发起远程命令)

前言

受2020年初的新型肺炎病毒影响,多日宅在家中无聊至极,就在琢磨一套调度系统,想用来管理维护大数据调度作业。
写了一多半停下来整改BUG,发现切换主机环境后,发现之前写的远程shell执行引擎失灵,怎么调试作业都提不到application上(之前在公司的环境下是能够正常提交的)无奈之下只能重新寻找实现方案,现总结出一套完整的解决方案,集中模板配置,可实现向多主机发送shell远程命令,较之前的实现方案当真是简便了许多,这里做一下分享。

pom依赖支持

博主选用的编程框架为SpringBoot,这里假设我们需要向两台机器发送shell远程命令,先向pom.xml添加依赖:

		<!-- @ConfigurationProperties注解支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<!-- shell认证支持 -->
		<dependency>
			<groupId>ch.ethz.ganymed</groupId>
			<artifactId>ganymed-ssh2</artifactId>
			<version>262</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.6</version>
		</dependency>

配置yml

向application.yml添加信息:

jackroy1:
  host: 172.26.20.80
  port: 22
  user: root
  password: jack_roy1

jackroy2:
  host: 172.26.20.81
  port: 22
  user: root
  password: jack_roy2
  
# 根据需要还可设置多台主机信息

建类

创建第一台linux实体类CentOSOneEntity :

package com.jackroy.www.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Component
@ConfigurationProperties(prefix="jackroy1")
public class CentOSOneEntity {
    /* 主机(IP) */
    private String host;
    /* 连接端口 */
    private  int port;
    /* 编码 */
    private Charset charset = StandardCharsets.UTF_8;
    /* 用户 */
    private String user;
    /* 密码 */
    private String password;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public Charset getCharset() {
        return charset;
    }

    public void setCharset(Charset charset) {
        this.charset = charset;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

创建第二台linux实体类CentOSTwoEntity :

package com.jackroy.www.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Component
@ConfigurationProperties(prefix="jackroy2")
public class CentOSTwoEntity {
    /* 主机(IP) */
    private String host;
    /* 连接端口 */
    private  int port;
    /* 编码 */
    private Charset charset = StandardCharsets.UTF_8;
    /* 用户 */
    private String user;
    /* 密码 */
    private String password;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public Charset getCharset() {
        return charset;
    }

    public void setCharset(Charset charset) {
        this.charset = charset;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

根据需要还可以创建更多的主机实体类,再创建登录、执行类SSHRegister :

package com.jackroy.www.entity;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

public class SSHRegisterEntity {
    /* 连接器 */
    private Connection connect;
    /* 主机(IP) */
    private String host;
    /* 连接端口 */
    private  int port;
    /* 编码 */
    private Charset charset;
    /* 用户 */
    private String user;
    /* 密码 */
    private String password;

    public SSHRegisterEntity(CentOSEntity centOSEntity) {
        this.host = centOSEntity.getHost();
        this.port=centOSEntity.getPort();
        this.user = centOSEntity.getUser();
        this.charset = centOSEntity.getCharset();
        this.password = centOSEntity.getPassword();
    }

    /**
     * 登录Centos主机
     */
    private boolean login() {
        connect = new Connection(host,port);
        try {
            connect.connect();
            return connect.authenticateWithPassword(user, password);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取返回信息
     */
    public StringBuilder processStdout(InputStream in) {
        byte[] buf = new byte[1024];
        StringBuilder builder = new StringBuilder();
        try {
            int length;
            while ((length = in.read(buf)) != -1) {
                builder.append(new String(buf, 0, length));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder;
    }

    /**
     * exec shell命令
     */
    public StringBuilder exec(String shell) throws IOException {
        InputStream inputStream = null;
        StringBuilder result = new StringBuilder();
        try {
            // 认证登录信息
            if (this.login()) {
                // 登陆成功则打开一个会话
                Session session = connect.openSession();
                session.execCommand(shell);
                inputStream = session.getStdout();
                result = this.processStdout(inputStream);
                connect.close();
            }
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
        }
        return result;
    }
}

调用

调用方法如下:

@Autowired
CentOSOneEntity centOSOneEntity;
@Autowired
CentOSTwoEntity centOSTwoEntity;

public int submit() throws IOException {
	// 主机1
	SSHRegisterEntity sshRegisterEntity1 = new SSHRegisterEntity(centOSOneEntity);
	// 主机2
	SSHRegisterEntity sshRegisterEntity2 = new SSHRegisterEntity(centOSTwoEntity);
	// 向主机1发送命令
    StringBuilder stringBuilder1 = sshRegisterEntity1.exec("ll /root/");
    // 向主机2发送命令
    StringBuilder stringBuilder2 = sshRegisterEntity2.exec("ll /root/");
    // 返回信息1
    System.out.println(stringBuilder1.toString());
     // 返回信息2
    System.out.println(stringBuilder2.toString());
	return null;
 }

后记

根据需要,配置多台机器灵活使用,大家在操作的时候有什么问题,可以下方留言交流。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值