前台的效果图:
后台代码:
我将远程服务器的连接、关闭与命令处理,因项目中多次的调用,规到一个类中。
LinuxConnect中有多个LinuxConnect方便自己注意区别;后面还有一篇;服务器程序管理的功能;
LinuxConnect.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class LinuxConnect {
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
private static Session session;
static BufferedReader reader = null;
static Channel channel = null;
/**
* 连接到指定的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();
} catch (JSchException e) {
e.printStackTrace();
System.out.println(host+"connect error !");
return false;
}
return true;
}
/**
* 远程连接Linux 服务器 执行相关的命令
*
* @param commands 执行的脚本
* @param user 远程连接的用户名
* @param passwd 远程连接的密码
* @param host 远程连接的主机IP
* @return 最终命令返回信息
*/
public static Map<String, String> runDistanceShell(String[] commands) {
Map<String, String> map = new HashMap<>();
StringBuilder stringBuffer;
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);
}
channel.disconnect();
//每个命令存储自己返回数据-用于后续对返回数据进行处理
map.put(command, stringBuffer.toString());
}
} catch (IOException | JSchException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (channel != null) {
channel.disconnect();
}
session.disconnect();
}
return map;
}
/**
* 远程连接Linux 服务器 执行相关的命令
*
* @param command 执行的脚本
* @param user 远程连接的用户名
* @param passwd 远程连接的密码
* @param host 远程连接的主机IP
* @return 最终命令返回信息
*/
public static Map<String, String> runDistanceShell(String command) {
Map<String, String> map = new HashMap<>();
StringBuilder stringBuffer;
try {
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);
}
channel.disconnect();
//每个命令存储自己返回数据-用于后续对返回数据进行处理
map.put(command, stringBuffer.toString());
} catch (IOException | JSchException e) {
e.printStackTrace();
} finally {
}
return map;
}
/**
* 直接在本地执行 shell
*
* @param commands 执行的脚本
* @return 执行结果信息
*/
public static Map<String, String> runLocalShell(String[] commands) {
Runtime runtime = Runtime.getRuntime();
Map<String, String> map = new HashMap<>();
StringBuilder stringBuffer;
BufferedReader reader;
Process process;
for (String command : commands) {
stringBuffer = new StringBuilder();
try {
process = runtime.exec(command);
InputStream inputStream = process.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
String buf;
while ((buf = reader.readLine()) != null) {
//舍弃PID 进程信息
if (buf.contains("PID")) {
break;
}
stringBuffer.append(buf.trim()).append(LINE_SEPARATOR);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
//每个命令存储自己返回数据-用于后续对返回数据进行处理
map.put(command, stringBuffer.toString());
}
return map;
}
public boolean judgeString(String str) {
Pattern pattern = Pattern.compile("-?[0-9]+\\.?[0-9]*");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}else {
return true;
}
}
public void close() {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (channel != null) {
channel.disconnect();
}
session.disconnect();
}
}
这里为方便定义了一个实体类:
MonitorInfor.java
各位自己get与set下
private Integer id;
private String ip;//服务器IP
private String useName;//服务登录名
private String password;//服务登录密码
private static final double cpuTotal=100;//cpu总计
private double cpuFree;//cpu空闲率
private double cpuUS;//cpu使用率
private double ramUS;//内存使用率
private double swapUS;//交换空间使用率
private double diskUS;//磁盘空间使用率
private double ramTotal;//内存总空间
private double swapTotal;//交换空间总空间
private double diskTotal;//磁盘空间总空间
private double ramFree;//内存空闲空间
private double swapFree;//交换空间空闲空间
private double diskFree;//磁盘空间空间
private double ramUser;//内存已使用空间
private double swapUser;//交换空间已使用空间
private double diskUser;//磁盘已使用空间
private String UpdateTime;//服务器资源监控刷新时间
private String programName;//程序名称
private String programPath;//程序部署路径
private String ProcessNumber;//程序进程
private String programType;//程序状态
private String line;
核心代码,执行linux命令得到返回集;并对信息进行处理;可能各位执行后会得不到数据,请你各位使用debug执行;看命令执行后是否有返回信息;如果有再看处理过程遇到的问题;因服务器不同返回的信息格式会有差异。
LinuxStateForShell.java
核心我是从这文章复制进行测试修改成的:https://www.cnblogs.com/longronglang/p/6936318.html
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.Dao.MonitorInfor;
import com.util.DateTimeUtil;
public class LinuxStateForShell {
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 LinuxConnect conn= new LinuxConnect();
/**
* 处理 shell 返回的信息
* 具体处理过程以服务器返回数据格式为准
* 不同的Linux 版本返回信息格式不同
* @param result shell 返回的信
* @return 终处理后的信息
*/
private static MonitorInfor disposeResultMessage(Map<String, String> result) {
StringBuilder buffer = new StringBuilder();
MonitorInfor monitorInfor=new MonitorInfor();
for (String command : COMMANDS) {
String commandResult = result.get(command);
if (null == commandResult) continue;
if (command.equals(CPU_MEM_SHELL)) {
String[] strings = commandResult.split(conn.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 = "CPU 用户使用占有:";
try {
cpuStr += line.split(":")[1].split(",")[0].replace("US", "");
monitorInfor.setCpuUS(Double.valueOf(cpuStr.split(":")[1].trim()));
} catch (Exception e) {
e.printStackTrace();
cpuStr += "计算过程出错";
}
buffer.append(cpuStr).append(conn.LINE_SEPARATOR);
//处理内存KIB MEM : 32379960 TOTAL, 22603716 free, 7298292 used, 2477952 BUFF/CACHE
} else if (line.startsWith("KIB MEM")) {
String memStr ;
try {
// memStr += line.split(":")[1]
// .replace("TOTAL", "总计")
// .replace("FREE", "空闲")
// .replace("USED", "已使�?")
// .replace("BUFF/CACHE", "缓存");
memStr = line.split(":")[1]
.replace("TOTAL", "")
.replace("FREE", "")
.replace("USED", "")
.replace("BUFF/CACHE", "");
String[] meminfor=dataExtract(memStr);
for(int i=0;i<meminfor.length;i++) {
meminfor[i]+="K";
disposeUnit(meminfor[i]);
}
monitorInfor.setRamTotal(decimalFromat(disposeUnit(meminfor[0])));
monitorInfor.setRamFree(decimalFromat(disposeUnit(meminfor[1])));
monitorInfor.setRamUser(decimalFromat(disposeUnit(meminfor[2])));
monitorInfor.setRamUS(decimalFromat((monitorInfor.getRamUser()/monitorInfor.getRamTotal())*100));
} catch (Exception e) {
e.printStackTrace();
memStr = "计算过程出错";
buffer.append(memStr).append(conn.LINE_SEPARATOR);
continue;
}
buffer.append(memStr).append(conn.LINE_SEPARATOR);
//交换空间 KiB Swap: 16318460 total, 16318460 free, 0 used. 24519440 avail Mem
}else if(line.startsWith("KIB SWAP")) {
String swapStr;
try {
// swapStr += line.split(":")[1]
// .replace("TOTAL", "总计")
// .replace("FREE", "空闲")
// .replace("USED", "已使�?")
// .replace(".", ",")
// .replace("AVAIL MEM", "缓存");
swapStr = line.split(":")[1]
.replace("TOTAL", "")
.replace("FREE", "")
.replace("USED", "")
.replace(".", ",")
.replace("AVAIL MEM", "");
String[] swapinfor=dataExtract(swapStr);
for(int j=0;j<swapinfor.length;j++) {
swapinfor[j]+="K";
swapinfor[j]=String.valueOf(disposeUnit(swapinfor[j]));
}
monitorInfor.setSwapTotal(changeDouble(swapinfor[0]));
monitorInfor.setSwapFree(changeDouble(swapinfor[1]));
monitorInfor.setSwapUser(changeDouble(swapinfor[2]));
monitorInfor.setSwapUS(decimalFromat((monitorInfor.getSwapUser()/monitorInfor.getSwapTotal())*100));
} catch (Exception e) {
e.printStackTrace();
swapStr = "计算过程出错";
buffer.append(swapStr).append(conn.LINE_SEPARATOR);
continue;
}
buffer.append(swapStr).append(conn.LINE_SEPARATOR);
}
}
} else if (command.equals(FILES_SHELL)) {
//处理系统磁盘状�??
buffer.append("系统磁盘状�??:");
String disk;
try {
disk=disposeFilesSystem(commandResult).toString();
disk=disk.split(":")[1]
.replace("总计", "")
.replace("已使�?", "")
.replace("空闲", "");
String[] disklist =dataExtract(disk);
monitorInfor.setDiskTotal(changeDouble(disklist[0]));
monitorInfor.setDiskUser(changeDouble(disklist[1]));
monitorInfor.setDiskFree(changeDouble(disklist[2]));
monitorInfor.setDiskUS(decimalFromat((monitorInfor.getDiskUser()/monitorInfor.getDiskTotal())*100));
buffer.append(disposeFilesSystem(commandResult)).append(conn.LINE_SEPARATOR);
System.out.println("打印磁盘�?"+disposeFilesSystem(commandResult));
} catch (Exception e) {
e.printStackTrace();
disk="计算过程出错";
buffer.append(disk).append(conn.LINE_SEPARATOR);
}
}
}
return monitorInfor;
}
//处理系统磁盘状�??
/**
* 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(conn.LINE_SEPARATOR);
// final String PATTERN_TEMPLATE = "([a-zA-Z0-9%_/]*)\\s";
double size = 0;
double used = 0;
for (int i = 0; i < strings.length; i++) {
if (i == 0) continue;
int temp = 0;
int n=0;
String old = null;
int oldIndex=0;
int number=0;
for (String s : strings[i].split("\\b")) {
n++;
String lastIndex = s.substring(s.length() - 1);
String num = s.substring(0,s.length() - 1);
num=num.trim();
if((s.length()==1&&conn.judgeString(lastIndex))||(s.length()==1&&s.equals("."))||(n-oldIndex==1&&oldIndex>0)) {
if(conn.judgeString(s)) {
old=s;
oldIndex=n;
continue;
}
if(s.equals(".")&&(n-oldIndex==1)) {
old+=s;
oldIndex=n;
continue;
}
String end = s.substring(s.length() - 1);
if((end.equals("G")||end.equals("T")||end.equals("M")||end.equals("K")||end.equals("KM"))&&(n-oldIndex==1)) {
old+=s;
num=old.substring(0,old.length() - 1);
s=old;
}else {
old=null;
oldIndex=0;
temp++;
}
}else if(oldIndex>0&&num.equals("")) {
old=null;
oldIndex=0;
temp++;
}
if (!conn.judgeString(num)) {
continue;
}else {
if (!s.trim().isEmpty()) {
++temp;
if (temp == 1) {
size += disposeUnit(s);
}else if (temp == 2){
used += disposeUnit(s);
}
}
}
}
}
return new StringBuilder().append("系统磁盘使用情况:").append("总计 ").append(size).append(", 已使�?").append(used).append(",空闲")
.append(size - used).toString();
// return new StringBuilder().append("系统磁盘使用情况:").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 double disposeUnit(String s) {
try {
s = s.toUpperCase();
String lastIndex = s.substring(s.length() - 1);
String num = s.substring(0, s.length() - 1);
double parseInt = Double.parseDouble(num);
if (lastIndex.equals("G")) {
return parseInt;
} else if (lastIndex.equals("T")) {
return parseInt * 1024;
} else if (lastIndex.equals("M")) {
return parseInt / 1024;
} else if (lastIndex.equals("K") || lastIndex.equals("KB")) {
return parseInt / (1024 * 1024);
}
} catch (NumberFormatException e) {
e.printStackTrace();
return 0;
}
return 0;
}
public static String[] dataExtract(String str){
MonitorInfor monitor =new MonitorInfor();
String[] datainfor=str.split(",");
for(int i=0;i<datainfor.length;i++) {
datainfor[i]=datainfor[i].trim();
}
return datainfor;
}
public static double decimalFromat(double s) {
BigDecimal bg = new BigDecimal(s);
double d3 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
return d3;
}
public static List<MonitorInfor> getData(List<MonitorInfor> Infor){
List<MonitorInfor> MonitorInforList =new ArrayList<MonitorInfor>();
for(int i=0;i<Infor.size();i++) {
if(conn.connect(Infor.get(i).getUseName(),Infor.get(i).getPassword(),Infor.get(i).getIp()))
{
Map<String, String> result = conn.runDistanceShell(COMMANDS);
MonitorInfor monitor=disposeResultMessage(result);
monitor.setIp(Infor.get(i).getIp());
monitor.setUpdateTime(DateTimeUtil.getDateToString(System.currentTimeMillis()));
MonitorInforList.add(monitor);
}else {
continue;
}
}
// H2ReadUpdata h2=new H2ReadUpdata();
// h2.updata(MonitorInforList);
return MonitorInforList;
}
public static double changeDouble(String s) {
return decimalFromat(Double.valueOf(s));
}
public static String changeString(Double s) {
return String.valueOf(s);
}
public static void main(String[] args) {
if(conn.connect("用户", "密码", "ip地址")){
Map<String, String> result = conn.runDistanceShell(COMMANDS);
MonitorInfor monitor=disposeResultMessage(result);
System.out.println(monitor.toString());
}else {
System.out.println("连接不上");
}
}
}
核心代码中还调用了一个我自己做的时间转换的类:
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author yangxin-ryan
*/
public class DateTimeUtil {
public static Long parse(String startTime, String timeFormat){
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
Date date = null;
try {
date = sdf.parse(startTime);
} catch (ParseException e) {
e.printStackTrace();
}
return date.getTime();
}
public static String format(Date datetime, String retTimeFmt) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(retTimeFmt);
String date = simpleDateFormat.format(datetime);
return Timestamp.valueOf(date).toString();
}
//时间戳转时间类型
public static String getDateToString(long time) {
Date d = new Date(time);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sf.format(d);
}
//时间类型转时间戳
public static long getStringToDate(String time) {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
try {
date = sf.parse(time);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return date.getTime();
}
}
后面看各位自己调试了。只能帮到这了。