java中远程监控Linux主机CPU及内存代码实现

本文介绍如何使用vmstat命令高效监控Linux主机系统的CPU和内存使用情况,提供远程登录实例和详细解析,避免了使用top命令的复杂性和误判问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于远程监控Linux主机系统CPU,内存使用情况,以前也使用了top等命令,但是最后还是觉得使用vmstat比较好.


运行top命令获得系统CPU使用情况有两个缺点,


第一运行top命令,执行的shell语句相对复杂.
用top命令获得CPU使用情况的shell语句
top -b -n 2 | grep Cpu |sed 1d | awk '{print $5}' | cut -f 1 -d "."
第二:有时候系统峰值时间很短暂,容易造成误判.




注意:运行本例子,你还需要下载第三方ganymed-ssh2-build251beta1.jar,改软件主要用于通过ssh远程登录被监控主机.


import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import java.io.*;
public class test{

public static void main(String[] args) {
Connection conn = null;
boolean isAuthenticated = false;
try
{
/* Create a connection instance */


conn = new Connection(hostname); // hostname 你要远程登录的主机IP地址,如10.0.2.1


/* Now connect */

conn.connect();

/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/


isAuthenticated = conn.authenticateWithPassword(username, password); //你要远程登录的主机的用户名及密码,如admin/123456
//System.out.println("authenticate sucess ...........................");
if (isAuthenticated == false)
System.out.println("SSH Login  Authentication failed.");
else
{
/* Create a session */
Session sess = conn.openSession();
System.out.println(new SysCpuInfo(sess).getCPUInfo());
/*注意,一个session只能执行一次shell,因此,如果你要再执行shell的话,必须重新创建一个session*/
sess.close();
sess = conn.openSession();
System.out.println(new SysMemInfo(sess).getMEMInfo());
sess.close();
}
}catch(Exception e){System.out.println(e.toString());}


}


1.读取CPU信息(SysCpuInfo.java)


import java.io.*;
import java.lang.*;
import java.util.StringTokenizer;


import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;


public class SysCpuInfo {


private int CPU_IDLE=0;
int processStatus =0;

public SysCpuInfo(Session session)
{
InputStream is = null;
BufferedReader brStat = null;
StringTokenizer tokenStat=  null ;
Session sess = null;
String str = "";
int i=0,j=0,cpuidle=0;

/**
* 对于执行linux shell.
*/
try{
sess = session;
sess.execCommand("vmstat 2 10 ");
/**
* 执行vmstat命令获得系统CPU负载情况,vmstat 2 10表示2秒钟输出一次共输出10组数据
* 显示结果如下:
* [mon724@v0A-202-40-18 ~]$ vmstat 2 10
* procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
* r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
* 1  0  41328  58860 199292 1877728    0    0     2    23    0    0  2  0 98  0  0
* 0  0  41328  58744 199292 1877884    0    0     0     0 1080 1057  3  0 96  0  0
* 0  0  41328  58084 199300 1878036    0    0     0   250 1310 1258  6  0 94  0  0
* 0  0  41328  57844 199300 1878148    0    0     0    32  761  697  3  0 97  0  0
* 0  0  41328  57852 199304 1878224    0    0     0   214  630  593  1  1 98  0  0
* 0  0  41328  56984 199304 1878372    0    0     0    50 1033  881  6  0 94  0  0
* 0  0  41328  56860 199304 1878440    0    0     0     0  536  578  2  0 98  0  0
* 1  0  41328  56868 199308 1878552    0    0     0   200  545  581  1  0 99  0  0
* 0  0  41328  56876 199308 1878644    0    0     0   102  628  663  1  0 99  0  0
* 0  0  41328  56876 199308 1878696    0    0     0   118  615  580  3  0 96  0  0 
*/
is = new StreamGobbler(sess.getStdout());


brStat = new BufferedReader(new InputStreamReader(is));
/*先读取第一行Title信息
* procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
* */
brStat.readLine();
/*读取第二行Title信息读取第三行信息
*  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
* */
brStat.readLine();

/*读取第三行信息
*  1  0  41328  58860 199292 1877728    0    0     2    23    0    0  2  0 98  0  0
*  注意每次执行vmstat命令时,此行信息基本不变,因此不做为抽取数据使用
* */
brStat.readLine();
/*读取第4行到第12行信息
*/
for(j=0;j<9;j++)
{
str = brStat.readLine();
if(str==null)
break;
tokenStat = new StringTokenizer(str);
for(i=0;i<14;i++)
{
tokenStat.nextToken();
}
cpuidle = cpuidle+new Integer(tokenStat.nextToken()).intValue();
}
CPU_IDLE = new Double(cpuidle/9).intValue();

}catch(Exception e){System.out.println(e.toString());}
}

public int getCPUInfo()
{
return CPU_IDLE;
}


}


2.读取内存信息(SysMemInfo.java)
import java.io.*;
import java.lang.*;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.StringTokenizer;


import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;


public class SysMemInfo {




private int MEM_INFO=0;



public SysMemInfo(Session session,String hostname)
{
InputStream is = null;
BufferedReader brStat = null;
StringTokenizer tokenStat=  null ;
Session sess = null;
String str = "";
int i=0,j=0,free=0,buff=0,cache=0,totalmemory=0,memidle=0;
double memused=0;
DataBaseCon datacon = null;
ResultSet reset ;
Statement stmt = null;
/**
* 对于执行linux shell中存在重定向和管道过滤的命令,需要使用命令组的形式.
*/
try{
datacon = new DataBaseCon();
stmt = datacon.getDBconnection().createStatement();

reset = stmt.executeQuery("select TOTAL_MEMORY from machine_info where machine_ip='"+hostname+"'");
while(reset.next())
{
totalmemory = reset.getInt("TOTAL_MEMORY");
}
sess = session;
sess.execCommand("vmstat 2 10 ");
/**
* 执行vmstat命令获得系统CPU负载情况,vmstat 2 10表示2秒钟输出一次共输出10组数据
* 显示结果如下:
* [mon724@v0A-202-40-18 ~]$ vmstat 2 10
* procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
* r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
* 1  0  41328  58860 199292 1877728    0    0     2    23    0    0  2  0 98  0  0
* 0  0  41328  58744 199292 1877884    0    0     0     0 1080 1057  3  0 96  0  0
* 0  0  41328  58084 199300 1878036    0    0     0   250 1310 1258  6  0 94  0  0
* 0  0  41328  57844 199300 1878148    0    0     0    32  761  697  3  0 97  0  0
* 0  0  41328  57852 199304 1878224    0    0     0   214  630  593  1  1 98  0  0
* 0  0  41328  56984 199304 1878372    0    0     0    50 1033  881  6  0 94  0  0
* 0  0  41328  56860 199304 1878440    0    0     0     0  536  578  2  0 98  0  0
* 1  0  41328  56868 199308 1878552    0    0     0   200  545  581  1  0 99  0  0
* 0  0  41328  56876 199308 1878644    0    0     0   102  628  663  1  0 99  0  0
* 0  0  41328  56876 199308 1878696    0    0     0   118  615  580  3  0 96  0  0 
*/
is = new StreamGobbler(sess.getStdout());


brStat = new BufferedReader(new InputStreamReader(is));
/*先读取第一行Title信息
* procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
* */
brStat.readLine();
/*读取第二行Title信息读取第三行信息
*  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
* */
brStat.readLine();

/*读取第三行信息
*  1  0  41328  58860 199292 1877728    0    0     2    23    0    0  2  0 98  0  0
*  注意每次执行vmstat命令时,此行信息基本不变,因此不做为抽取数据使用
* */
brStat.readLine();
/*读取第4行到第12行信息
*/
for(j=0;j<9;j++)
{
str = brStat.readLine();

if(str==null)
break;
tokenStat = new StringTokenizer(str);
/*跳过每行前3列信息
* r  b   swpd   
    * 1  0  41328
* */
for(i=0;i<3;i++)
{
tokenStat.nextToken();
}
/*
* 读取每行中free,buff,cache列信息
* r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
    * 1  0  41328  58860 199292 1877728    0    0     2    23    0    0  2  0 98  0  0

* */
/*读取free的信息*/
free =  free+new Integer(tokenStat.nextToken()).intValue();
//SysLogger.log("free is :"+free);
/*读取buff的信息*/
buff =  buff+new Integer(tokenStat.nextToken()).intValue();
//SysLogger.log("buff is :"+buff);
/*读取cache的信息*/
cache = cache+new Integer(tokenStat.nextToken()).intValue();
//SysLogger.log("cache is :"+cache);

}
/*
* ===========================================================
* 获得内存IDLE的平均值,因为读取了9行数据因此需要除于9得出平均值
* 对于应用程序来说系统真正的内存空余是free+buff+cache之和
* ===========================================================
* */
memidle = (free+buff+cache)/9;
/*获得内存占用率*/
memused = ((totalmemory-memidle)*100)/totalmemory;
//SysLogger.log("SysMemInfo memidle is :"+memidle+"===memused is :"+memused);
MEM_INFO = new Double(memused).intValue();
SysLogger.log("SysMemInfo MEM_INFO IS : "+MEM_INFO);
}catch(Exception e){SysLogger.log("SysMemInfo error at line 39 :"+e.toString());}
}


public int getMEMInfo()
{
return MEM_INFO;
}
}

<think>好的,我需要帮助用户通过Java Proxy代理在运行接口时远程获取Linux系统的CPU利用率。首先,我需要理解用户的需求。他们想使用Java的动态代理机制,在调用某个接口的方法时,触发获取远程Linux服务器的CPU利用率。 首先,我得确定如何通过Java代码获取远程服务器的CPU利用率。通常,获取LinuxCPU使用率可以通过读取/proc/stat文件,然后计算差值。但因为是远程服务器,可能需要通过SSH连接执行命令来获取这些数据。常用的Java库有JSch,可以用来执行SSH命令。 接下来,用户提到使用Java Proxy实现代理。动态代理通常用于在方法调用前后插入自定义逻辑,这里需要在接口方法被调用时触发获取CPU使用率的操作。因此,我需要定义一个接口,然后创建动态代理,在调用接口方法时执行获取CPU利用率的代码。 然后需要考虑的是如何将这两部分结合起来。代理类中的invoke方法会在目标方法被调用时执行,所以在这里调用获取CPU利用率的方法。同时,远程执行命令可能会涉及异常处理和性能问题,需要妥善处理。 另外,示例代码需要展示动态代理的创建和使用,以及通过JSch执行远程命令的过程。还需要处理CPU利用率的计算逻辑,可能需要解析/proc/stat的数据,进行计算并返回结果。 需要注意的部分包括SSH连接的配置(如主机名、用户名、密码)、异常处理、资源释放(如断开SSH连接)以及CPU计算的准确性。此外,动态代理的正确使用方式,确保在调用任何接口方法时都会触发CPU获取的逻辑。 可能还需要提醒用户关于安全性的问题,比如使用密码直接写在代码中不安全,建议使用密钥认证或者配置管理。此外,频繁执行SSH命令可能会影响性能,需要考虑优化或缓存机制。 最后,生成相关问题,帮助用户深入理解相关技术点,如动态代理的原理、其他远程监控方法、更高效的CPU计算方式等。</think>### Java Proxy实现远程CPU监控示例 通过Java动态代理和SSH连接实现远程监控CPU利用率的步骤如下: 1. **定义监控接口** ```java public interface SystemMonitor { double getCpuUsage() throws Exception; } ``` 2. **创建代理处理器** ```java import com.jcraft.jsch.*; public class RemoteMonitorProxy implements InvocationHandler { private final String host; private final String user; private final String password; public RemoteMonitorProxy(String host, String user, String password) { this.host = host; this.user = user; this.password = password; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("getCpuUsage")) { return calculateCpuUsage(); } return null; } private double calculateCpuUsage() throws JSchException, IOException { JSch jsch = new JSch(); Session session = jsch.getSession(user, host, 22); session.setPassword(password); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); ChannelExec channel = (ChannelExec) session.openChannel("exec"); channel.setCommand("cat /proc/stat | grep '^cpu '"); InputStream in = channel.getInputStream(); channel.connect(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String statLine = reader.readLine(); session.disconnect(); return parseCpuUsage(statLine); } private double parseCpuUsage(String statLine) { String[] parts = statLine.split("\\s+"); long total = 0; for (int i = 1; i < parts.length; i++) { total += Long.parseLong(parts[i]); } long idle = Long.parseLong(parts[4]); return (1 - (double)idle/total) * 100; } } ``` 3. **使用代理对象** ```java public class Main { public static void main(String[] args) { SystemMonitor monitor = (SystemMonitor) Proxy.newProxyInstance( SystemMonitor.class.getClassLoader(), new Class[]{SystemMonitor.class}, new RemoteMonitorProxy("192.168.1.100", "user", "password") ); try { System.out.printf("CPU利用率: %.2f%%", monitor.getCpuUsage()); } catch (Exception e) { e.printStackTrace(); } } } ``` 关键要点说明: - 使用JSch库建立SSH连接[^2] - 通过`/proc/stat`计算CPU利用率 - 动态代理拦截方法调用 - 需要JDK8及以上环境
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值