[Spring boot configuration template] java remote shell command execution (initiated by remote commands to support multi-master)

[Spring boot configuration template] java remote shell command execution (initiated by remote commands to support multi-master)

Foreword

The impact of new pneumonia virus by early 2020, the house for several days at home bored, wondering in a dispatch system, want to use big data management and maintenance scheduling jobs.
He wrote a mostly stop rectification BUG, found after switching mainframe environment, was found written before the remote shell execution engine failure, how to debug jobs are not to mention frustration on application (before in the company's environment is the ability to properly submitted) only under Looking to re-implement the program, is now summed up a complete solution for centralized configuration templates, enabling remote shell command is sent to the multi-host, compared to the previous implementation is really a lot of simple, here to do some sharing.

pom rely on the support

Bloggers chosen programming framework for SpringBoot, is assumed here that we need to send a remote command shell to two machines, Xianxiang pom.xml add dependencies:

		<!-- @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

Add information to 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
  
# 根据需要还可设置多台主机信息

Built class

Create the first linux entity classes 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 create a second entity class 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;
    }
}

You can also create needed more hosts entity class, and then create a login, execution classes 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;
    }
}

transfer

Call as follows:

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

postscript

If necessary, use the flexibility to configure multiple machines, there is no problem when in operation, can exchange comments below.

Published 31 original articles · won praise 21 · views 20000 +

Guess you like

Origin blog.csdn.net/Jack_Roy/article/details/104213147