您的位置:首页 > 运维架构 > Linux

Linux 下 java 监控 程序运行

2015-11-16 14:33 435 查看
需求是:tomcat的java进程经常100%占用CPU,此时servlet也停止响应了,业务逻辑除了问题。

希望有一个在PC上跑的监控程序,能够在tomcat 100%占用cpu的时候杀死。同时tomcat自动重启。

过程:tomcat自动重启是通过脚本实现 start_tomcat.sh :

下一步就是要检测tomcat的进程的PID。命令是:test.sh

拿到CPU占用情况:

ps -p PID -o %cpu,%mem,cmd

这条命令是在java环境中执行 RunTime.exec:

.这篇博客的重点在于:

原本在bash下面执行的ps 命令,如果想通过java执行并且获得ps输出,需要以 exec(new String[]{"/bin/sh","-c","正常控制台执行的命令"}) 这种形式才可以。

参考【http://huajianhsiu.iteye.com/blog/1772775】,可能是多重重定向导致的错误。这个方法是可以通用的。

下面是监控源码

----------------------------------------------

public class Monitor {

/**
* @param args
*/
public static void main(String[] args) {

try {
double last =0;
while(true)
{
TimeUnit.SECONDS.sleep(10);
String pid =getPID();
if(pid==null||pid.trim().length()==0)
{
continue;
}
System.out.println(pid);
String info =getCPU(pid);
System.out.println(info);
double cur =Double.parseDouble(info);
if(last>80&&cur>80)
{
Kill();

}
else {
last=cur;
}
}

 
} catch (Exception e) {
 
}

 
 

}

 
public static void Kill ( ) throws Exception
{
String pid =getPID();

if(pid==null||pid.trim().length()==0)
return ;

Runtime rt = Runtime.getRuntime();
 
Process proc = rt.exec(new String[] { "/bin/sh","-c", "kill -9 "+pid});

BufferedReader stdInput = new BufferedReader(new 
    InputStreamReader(proc.getInputStream()));

  
}

public static String getPID()  throws Exception

    {
Runtime rt = Runtime.getRuntime();
 
Process proc = rt.exec(new String[] { "/bin/sh","-c", "/home/apps/test.sh"});

BufferedReader stdInput = new BufferedReader(new 
    InputStreamReader(proc.getInputStream()));

BufferedReader stdError = new BufferedReader(new 
    InputStreamReader(proc.getErrorStream()));

// read the output from the command
StringBuilder sb =new StringBuilder();
String s = null;
while ((s = stdInput.readLine()) != null) {
  sb.append(s.trim());
}

  return sb.toString().trim();

    }
 
public static String getCPU(String pid)  throws Exception

    {
Runtime rt = Runtime.getRuntime();
 
Process proc = rt.exec(new String[] {"/bin/sh","-c","ps -p "+pid+" -o %cpu,%mem,cmd"});

BufferedReader stdInput = new BufferedReader(new 
    InputStreamReader(proc.getInputStream()));

// read the output from the command
StringBuilder sb =new StringBuilder();
String s = null;
while ((s = stdInput.readLine()) != null) {
  sb.append(s);
}

String []cp =sb.toString().split(" ");
return cp[3];
   

    }

}

-----------------------------------------------------------------------------------------------------------------------------

2015年11月17日10:33:05修正:经过晚上的测试,发现上述的getCPU函数并不能准确描述当前系统的CPU占用情况。

后来在阿里云里面采取了这个命令:top -bn2|grep 'Cpu(s)'|awk '{print $8}'|awk -F'%' '{print $1}'|tail -n1

取到的值为空闲状况;若这个值低于20,则认为cpu忙,10s检测一次,若连续2次都低于20,则进行重启tomcat. 修改如下。

public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static SimpleDateFormat sdf2 =new SimpleDateFormat("yyyy-MM-dd-HHmmss");
 
 public static void main(String[] args)
 {
   try
   {
     double last = 0.0D;
     for (;;)
     {
       TimeUnit.SECONDS.sleep(10L);
       
       String info = getCPU();
       System.out.println(sdf.format(new Date()) + "|" + info);
       double cur = Double.parseDouble(info);
       if ((last < 20.0D) && (cur < 20.0D)) {
         Kill();
       } else {
         last = cur;
       }
     }
   }
   catch (Exception e)
   {
     e.printStackTrace();
   }
 }
 
 public static void Kill()
   throws Exception
 {
   String pid = getPID();
   if ((pid == null) || (pid.trim().length() == 0)) {
     return;
   }
   Jstack(pid);
   Runtime rt = Runtim
c717
e.getRuntime();
   
   Process proc = rt.exec(new String[] { "/bin/sh", "-c", "kill -9 " + pid });
   
   BufferedReader stdInput = new BufferedReader(
     new InputStreamReader(proc.getInputStream()));
 }
 
 public static void Jstack(String pid) throws Exception
 {
 Runtime rt = Runtime.getRuntime();
   
   Process proc = rt.exec(new String[] { "/bin/sh", "-c", " jstack " + pid+" > /home/apps/"+sdf2.format(new Date())+".log" });
 }
 
 
 public static String getPID()
   throws Exception
 {
   Runtime rt = Runtime.getRuntime();
   
   Process proc = rt.exec(new String[] { "/bin/sh", "-c", "/home/apps/test.sh" });
   
   BufferedReader stdInput = new BufferedReader(
     new InputStreamReader(proc.getInputStream()));
   
   BufferedReader stdError = new BufferedReader(
     new InputStreamReader(proc.getErrorStream()));
   

   StringBuilder sb = new StringBuilder();
   String s = null;
   while ((s = stdInput.readLine()) != null) {
     sb.append(s.trim());
   }
   return sb.toString().trim();
 }
 
 public static String getCPU()
   throws Exception
 {
   Runtime rt = Runtime.getRuntime();
   
   Process proc = rt.exec(new String[] { "/bin/sh", "-c", "top -bn2|grep 'Cpu(s)'|awk '{print $8}'|awk -F'%' '{print $1}'|tail -n1" });
   
   BufferedReader stdInput = new BufferedReader(
     new InputStreamReader(proc.getInputStream()));
   

   StringBuilder sb = new StringBuilder();
   String s = null;
   while ((s = stdInput.readLine()) != null) {
     sb.append(s);
   }
   return sb.toString().trim();
 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java linux cpu 维护 to