【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;
 }

後記

根據需要,配置多臺機器靈活使用,大家在操作的時候有什麼問題,可以下方留言交流。

發佈了48 篇原創文章 · 獲贊 71 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章