远程调用Linux shell 命令 并获取服务器的使用情况 - 工具类

引入jar包

<!-- linux链接,远程操作服务器-->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>

工具类

package com.xx.common.utils.ssh;


import com.jcraft.jsch.*;
import com.nova.common.utils.Arith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * 远程调用Linux shell 命令
 *
 * @author wei.Li by 14-9-2.
 */

public class LinuxStateForShell {

    private static final Logger LOGGER = LoggerFactory.getLogger(LinuxStateForShell.class);

    public static final String CPU_MEM_SHELL = "top -b -n 1";
    public static final String FILES_SHELL = "df -hl";
    public static final String[] COMMANDS = {CPU_MEM_SHELL, FILES_SHELL};
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
    private static Session session;
    //SSH服务端口
    private static final int REMOTE_PORT = 22;
    //会话超时时间
    private static final int SESSION_TIMEOUT = 10000;
    //建立通讯超时时间
    private static final int TIMEOUT = 1000;

    //管道流超时时间(执行脚本超时时间)
    private static final int CHANNEL_TIMEOUT = 5000;

    public static void main(String[] args) {
        //Map<String, String> result = runDistanceShell("root", "Xiexie123.", "152.67.5.187");
        //String[] linux = disposeResultMessage(result);
        //for (String l :linux){
        //    System.out.println(l);
        //}
        int status = runRemoteScript("152.67.5.187", "root", "xxx", "/usr/local/java/tomcat/logs/reload_tomcat.sh");
        if (status == 0) {
            System.out.println("脚本执行成功");
        } else {
            System.out.println("脚本执行失败");
        }
    }


    /**
     * @author: Wang excellence
     * @date: 2021/7/1 15:09
     * @Description: 获取远程服务器的的cpu占用率,内存使用率,磁盘状况
     * 返回由数组返回  数组顺序为【0】cpu占用率,【1】内存使用率 【2】磁盘状况
     */
    public static String[] disposeResultMessage(Map<String, String> result) {
        String[] results = new String[3];
        if (result == null) {
            results = new String[]{"connect error !", "connect error !", "connect error !"};
            return results;
        }
        for (String command : COMMANDS) {
            String commandResult = result.get(command);
            if (null == commandResult) {
                continue;
            }
            if (command.equals(CPU_MEM_SHELL)) {
                String[] strings = commandResult.split(LINE_SEPARATOR);
                //将返回结果按换行符分割
                for (String line : strings) {
                    line = line.toUpperCase();//转大写处理
                    //处理CPU Cpu(s): 10.8%us,  0.9%sy,  0.0%ni, 87.6%id,  0.7%wa,  0.0%hi,  0.0%si,  0.0%st
                    if (line.startsWith("%CPU(S):")) {
                        String cpuStr = "";
                        try {
                            cpuStr += line.split(":")[1].split(",")[0].replace("US", "");
                            cpuStr += "%";
                        } catch (Exception e) {
                            e.printStackTrace();
                            cpuStr += "计算过程出错";
                        }
                        results[0] = cpuStr.trim();
                    } else if (line.startsWith("KIB MEM")) {
                        //处理内存 Mem:  66100704k total, 65323404k used,   777300k free,    89940k buffers
                        try {
                            line = line.replace("  ", " ").replace("  ", " ");
                            String[] mems = line.split(" ");
                            double parseInt = Integer.parseInt(mems[7]);
                            double parseInt1 = Integer.parseInt(mems[3]);
                            //System.err.println("内存使率:" + (Arith.div(parseInt,parseInt1,4))*100 + "%");
                            results[1] = ((Arith.div(parseInt, parseInt1, 4)) * 100 + "%");
                        } catch (Exception e) {
                            e.printStackTrace();
                            results[1] = "计算过程出错";
                            continue;
                        }
                    }
                }
            } else if (command.equals(FILES_SHELL)) {
                //处理系统磁盘状态
                try {
                    results[2] = (disposeFilesSystem(commandResult)).replace(" ", "");
                } catch (Exception e) {
                    e.printStackTrace();
                    results[2] = ("计算过程出错");
                }
            }
        }
        return results;
    }

    /**
     * @author: Wang excellence
     * @date: 2021/7/1 11:13
     * @Description: REMOTE_HOST 远程主机IP, USERNAME 远程主机用户名, PASSWORD 远程主机密码, SHELLPATH 脚本名称及路径,与上文要对上
     * 返回状态如果为0,则代表脚本被正确执行
     */
    public static int runRemoteScript(String REMOTE_HOST, String USERNAME, String PASSWORD, String SHELLPATH) {
        int result = 1;
        Session jschSession = null;
        try {
            JSch jsch = new JSch();
            //SSH授信客户端文件位置,一般是用户主目录下的.ssh/known_hosts
            //jsch.setKnownHosts("D:\\known_hosts");
            //jschSession.setConfig("StrictHostKeyChecking", "yes");
            jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
            jschSession.setConfig("StrictHostKeyChecking", "no");
            // 密码认证
            jschSession.setPassword(PASSWORD);
            // 建立session
            jschSession.connect(SESSION_TIMEOUT);
            //建立可执行管道
            ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec");
            // 执行脚本命令"sh /root/hello.sh zimug"
            channelExec.setCommand("sh " + SHELLPATH);
            // 获取执行脚本可能出现的错误日志
            channelExec.setErrStream(System.err);
            //脚本执行结果输出,对于程序来说是输入流
            InputStream in = channelExec.getInputStream();
            // 5 秒执行管道超时
            channelExec.connect(CHANNEL_TIMEOUT);
            // 从远程主机读取输入流,获得脚本执行结果
            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    //执行结果打印到程序控制台
                    //System.out.print(new String(tmp, 0, i));
                }
                if (channelExec.isClosed()) {
                    if (in.available() > 0) {
                        continue;
                    }
                    //获取退出状态,状态0表示脚本被正确执行
                    LOGGER.error("执行脚本操作:" + channelExec.getExitStatus());
                    //System.out.println("exit-status: "
                    //        + channelExec.getExitStatus());
                    result = channelExec.getExitStatus();
                    break;
                }
            }
            channelExec.disconnect();
        } catch (JSchException | IOException e) {
            e.printStackTrace();
        } finally {
            if (jschSession != null) {
                jschSession.disconnect();
            }
        }
        return result;
    }


    /**
     * 连接到指定的HOST
     *
     * @return isConnect
     * @throws JSchException JSchException
     */
    public static boolean connect(String user, String passwd, String host) {
        JSch jsch = new JSch();
        try {
            session = jsch.getSession(user, host, 22);
            session.setPassword(passwd);

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

            session.connect(TIMEOUT);
        } catch (JSchException e) {
            //e.printStackTrace();
            //System.out.println("connect error !");
            return false;
        }
        return true;
    }

    /**
     * 远程连接Linux 服务器 执行相关的命令
     *
     * @param user   远程连接的用户名
     * @param passwd 远程连接的密码
     * @param host   远程连接的主机IP
     * @return 最终命令返回信息
     */
    public static Map<String, String> runDistanceShell(String user, String passwd, String host) {
        String[] commands = COMMANDS;
        if (!connect(user, passwd, host)) {
            return null;
        }
        Map<String, String> map = new HashMap<>();
        StringBuilder stringBuffer;

        BufferedReader reader = null;
        Channel channel = null;
        try {
            for (String command : commands) {
                stringBuffer = new StringBuilder();
                channel = session.openChannel("exec");
                ((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;
                while ((buf = reader.readLine()) != null) {

                    //舍弃PID 进程信息
                    if (buf.contains("PID")) {
                        break;
                    }
                    stringBuffer.append(buf.trim()).append(LINE_SEPARATOR);
                }
                //每个命令存储自己返回数据-用于后续对返回数据进行处理
                map.put(command, stringBuffer.toString());
            }
        } catch (IOException | JSchException e) {
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (channel != null) {
                channel.disconnect();
            }
            session.disconnect();
        }
        return map;
    }

    //处理系统磁盘状态

    /**
     * Filesystem            Size  Used Avail Use% Mounted on
     * /dev/sda3             442G  327G   93G  78% /
     * tmpfs                  32G     0   32G   0% /dev/shm
     * /dev/sda1             788M   60M  689M   8% /boot
     * /dev/md0              1.9T  483G  1.4T  26% /ezsonar
     *
     * @param commandResult 处理系统磁盘状态shell执行结果
     * @return 处理后的结果
     */
    private static String disposeFilesSystem(String commandResult) {
        String[] strings = commandResult.split(LINE_SEPARATOR);

        // final String PATTERN_TEMPLATE = "([a-zA-Z0-9%_/]*)\\s";
        int size = 0;
        int used = 0;
        for (int i = 0; i < strings.length - 1; i++) {
            if (i == 0) {
                continue;
            }

            int temp = 0;
            for (String s : strings[i].split("\\b")) {
                if (temp == 0) {
                    temp++;
                    continue;
                }
                if (!s.trim().isEmpty()) {
                    if (temp == 1) {
                        size += disposeUnitG(s);
                        temp++;
                    } else {
                        used += disposeUnitG(s);
                        temp = 0;
                    }
                }
            }
        }
        return new StringBuilder().append("大小 ").append(size).append("G , 已使用").append(used).append("G ,空闲")
                .append(size - used).append("G").toString();
    }

    /**
     * 处理单位转换
     * K/KB/M/T 最终转换为G 处理
     *
     * @param s 带单位的数据字符串
     * @return 以G 为单位处理后的数值
     */
    private static int disposeUnitG(String s) {

        try {
            s = s.toUpperCase();
            String lastIndex = s.substring(s.length() - 1);
            String num = s.substring(0, s.length() - 1);
            int parseInt = Integer.parseInt(num);
            if ("G".equals(lastIndex)) {
                return parseInt;
            } else if ("T".equals(lastIndex)) {
                return parseInt * 1024;
            } else if ("M".equals(lastIndex)) {
                return parseInt / 1024;
            } else if ("K".equals(lastIndex) || "KB".equals(lastIndex)) {
                return parseInt / (1024 * 1024);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return 0;
        }
        return 0;
    }

}
posted @   xiexie0812  阅读(205)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示