linux定时结束java进程_使用zt-exec库定时清理linux休眠进程

在几个月前上线的一个采集项目,构架是基于java + selenium + chromedriver + chrome实现的采集。至于为哈不直接用jsoup或httpclient实现采集功能,是因为很多被采集页面都是通过js来渲染内容的,所以必须用webdriver+chrome来模拟真正的浏览器访问来采集。

每隔一段时间就会出采集失败问题,出现的时间没有规律,可能两天出现一次,可能一星期出现一次,可能一个月出现一次....

用linux top命令来查看服务器,会发现很多的chromedriver和chrome的进程

用ps命令查看服务器

ps -aux | grep chrome

b3381d72505d5f739055162adf7ca2a3.png

存在状态为Sl和Z的休眠进程和僵尸进程,启动时间都不是当天,根据系统本身业务逻辑,进程不会存在运行那么长时间的情况。而java进程则全部都能正常关闭,但java进程启动的chromedriver和chrome进程不一定能同时关闭,目前出现这种问题的原因未找到。

最初想用命令把卡死的进程查出来批量杀掉

ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9 //杀死僵尸进程

结果发现只能查杀Z状态的僵尸进程,Sl状态的进程,一部分是正常的,一部分是需要杀死的(启动时间为Nov07,Nov06的进程需要杀掉),至于哪些需要杀死,需要通过人工判断启动时间来确定是否需要杀掉进程。

之前一直忙时,都是先通过ps命令把chromedriver和chrome相关进程查询出来,然后通过人工判断进程是否属于休眠状态,再手工kill杀掉进程。

最近有空了,本着能程序解决,就绝不要人工维护,把之前的手工杀休眠进程操作程序化。一开始想直接通过java的Runtime.getRuntime().exec()代码调用linux命令操作的,不过在java常用类库中(https://www.21doc.net/java/awesomejava#processes),找到zt-exec库,可以简化命令行调用操作。

程序化的代替人工维护实现定时清理休眠进程代码如下:

import org.apache.log4j.Logger;

import org.apache.log4j.RollingFileAppender;

import org.zeroturnaround.exec.ProcessExecutor;

import org.zeroturnaround.exec.stream.LogOutputStream;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class ProcessKill {

private static Logger log = Logger.getLogger(ProcessKill.class);

public ProcessKill(){

}

public void run(){

try{

List> list = new ArrayList>();

// 先通过ps aux | grep chrome命令,获取所有包含chrome文本内容的进程

new ProcessExecutor().command("/bin/sh","-c","ps aux | grep chrome")

.redirectOutput(new LogOutputStream() {

protected void processLine(String line) {

log.info("line========" + line);

List lines = split(line.trim());

// 判断进程启动时间,确定是否为执行超时休眠的进程

String time = lines.get(8);

String format = "[0-5][0-9]:[0-5][0-9]";

Pattern p = Pattern.compile(format);

Matcher m = p.matcher(time);

boolean result = m.find();

if(result == true) {

log.info("time ========" + time + " " + result);

}

else{

log.info("time xxxxxxxx" + time + " " + result);

list.add(lines);

}

}

})

.execute();

log.info("list========size:" + list.size());

list.forEach(l->{

log.info("list line========" + l);

});

for(int i = 0; i < list.size(); i++){

List strs = list.get(i);

try{

String pid = strs.get(1);

String stat = strs.get(7);

String time = strs.get(8);

String cmd = strs.get(10);

log.info("pid========" + pid + ", " + stat + ", " + time + ", " + cmd);

// 通过命令“kill -9 pid”杀掉进程

String output = new ProcessExecutor().command("/bin/sh","-c","kill -9 " + pid)

.readOutput(true).execute()

.outputUTF8();

log.info("kill========" + pid + ", " + output);

}

catch(Exception ex){

ex.printStackTrace();

}

}

}

catch(Exception e){

e.printStackTrace();

}

}

public List split(String s){

// ps aux | grep chrome 命令返回字段: USER,PID ,%CPU,%MEM,VSZ, RSS,TTY,STAT,START,TIME,COMMAND

List list = new ArrayList();

int blankCount = 0;

StringBuffer sff = new StringBuffer();

for(int i = 0; i < s.length(); i++){

char c = s.charAt(i);

if(list.size() < 10){

if(c != ' '){

sff.append(c);

blankCount = 0;

}

else if(c == ' '){

blankCount++;

}

if(blankCount == 1){

list.add(sff.toString());

sff = new StringBuffer();

}

}

else{

sff.append(c);

}

}

if(sff.length() > 0){

list.add(sff.toString());

}

return list;

}

public static void setLogFile(String name){

Logger rootLogger = Logger.getRootLogger();

Enumeration en = rootLogger.getAllAppenders();

while (en.hasMoreElements()){

Object obj = en.nextElement();

if(obj instanceof RollingFileAppender){

RollingFileAppender file = (RollingFileAppender)obj;

file.setFile(name + ".log");

file.activateOptions();

}

}

}

public static void main(String[] args){

setLogFile("log/" + ProcessKill.class.getSimpleName());

new ProcessKill().run();

}

}

文末记录下ps和grep命令用法。

ps 显示瞬间进程的状态

参数:

-A :所有的进程均显示出来,与 -e 具有同样的效用;

-a : 显示现行终端机下的所有进程,包括其他用户的进程;

-u :以用户为主的进程状态 ;

x :通常与 a 这个参数一起使用,可列出较完整信息。

ps aux

USER:该进程属于那个使用者账号。

PID :该进程的进程ID号。

%CPU:该进程使用掉的 CPU 资源百分比;

%MEM:该进程所占用的物理内存百分比;

VSZ :该进程使用掉的虚拟内存量 (Kbytes)

RSS :该进程占用的固定的内存量 (Kbytes)

TTY :该进程是在那个终端机上面运作,若与终端机无关,则显示。另外, tty1-tty6 是本机上面的登入者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。

STAT:该程序目前的状态,主要的状态有:

R :该程序目前正在运作,或者是可被运作;

S :该程序目前正在睡眠当中,但可被某些讯号(signal) 唤醒。

T :该程序目前正在侦测或者是停止了;

Z :该程序应该已经终止,但是其父程序却无法正常的终止他,造成 zombie (疆尸) 程序的状态

START:该进程被触发启动的时间;

TIME :该进程实际使用 CPU 运作的时间。

COMMAND:该程序的实际指令。

ps -ef |grep java

UID :程序被该 UID 所拥有

PID :就是这个程序的 ID

PPID :则是其上级父程序的ID

C :CPU使用的资源百分比

STIME :系统启动时间

TTY :登入者的终端机位置

TIME :使用掉的CPU时间。

CMD :所下达的是什么指令

grep命令的常用格式为:grep  [选项]  ”模式“  [文件]

常用选项:

-E :开启扩展(Extend)的正则表达式。

-i :忽略大小写(ignore case)。

-v :反过来(invert),只打印没有匹配的,而匹配的反而不打印。

-n :显示行号

-w :被匹配的文本只能是单词,而不能是单词中的某一部分,如文本中有liker,而我搜寻的只是like,就可以使用-w选项来避免匹配liker

-c :显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用-cv选项是显示有多少行没有被匹配到。

-o :只显示被模式匹配到的字符串。

--color :将匹配到的内容以颜色高亮显示。

-A n:显示匹配到的字符串所在的行及其后n行,after

-B n:显示匹配到的字符串所在的行及其前n行,before

-C n:显示匹配到的字符串所在的行及其前后各n行,context

查看系统状态下的僵尸进程:

ps -ef | grep defunct  后面尖括号里是defunct的都是僵尸进程。

ps aux | grep -w 'Z' 其中状态为Z的代表僵尸进程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java的流传输的进度条_JAVA程序设计(17)----- 制作文件拷贝软件 进程 输入流输出流 NIO 进度条 底层拷贝 多线程...

使用NIO对文件进行底层拷贝(按照字节)多线程技术初级应用 不阻塞程序运行package com.lovo.homework01;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOu…

java 安卓调试_【转】Android 调试技术

一、JAVA层单步调试二、Native层单步调试三、JAVA层堆栈打印1. 在指定的函数内打印相关java调用 Log.d(TAG,Log.getStackTraceString(new Throwable()));2. 普通JAVA进程堆栈 ActivityManagerService.dumpStackTraces保存在系统设置dalvik.vm.stack-trace-file指定的文件data/a…

java spring4 jar包_spring jar包官方下载|

spring-web jar包是用来SSH配置的jar包 配置了监听器&#xff0c;还出现严重: Error configuring application listener of class org.springframework.web.context.ContextLoader就需要它&#xff0c;欢迎有需要的用户前来it猫扑下载&#xff01;spring-web.jar作用spring-web…

java 找不到符号 con_我的java程序运行时,提示找不到符号,求解!

我的java程序运行时&#xff0c;提示找不到符号&#xff0c;求解!关注:163 答案:4 mip版解决时间 2021-02-07 23:57提问者人潮拥挤你不在2021-02-06 23:57import java.awt.*;import java.awt.event.*;import java.applet.Applet;import java.applet.AudioClip;public class M…

java字符串为空抛出异常_Java 判断字符串是否为空的四种方法,及效率比较。

以下是Java 判断字符串是否为空的四种方法:方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低:if(s null ||"".equals(s));方法二: 比较字符串长度, 效率高, 是我知道的最好一个方法:if(s null || s.length() < 0);方法三: Java SE 6.0 才开始提供的方法, …

java抽组件_Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor

HtmlExtractor由2个子项目构成&#xff0c;html-extractor和html-extractor-web。html-extractor实现了数据抽取逻辑&#xff0c;是从节点&#xff0c;html-extractor-web提供web界面来维护抽取规则&#xff0c;是主节点。html-extractor是一个jar包&#xff0c;可通过maven引用…

mysql索引过多为什么会慢_mysql – 为什么索引使这个查询更慢?

摘要问题是由于b-trees的性质,字段不适合索引.说明假设你有一张表有500,000个掷硬币的结果,其中抛掷是1(头)或0(尾)&#xff1a;CREATE TABLE toss (id int NOT NULL AUTO_INCREMENT,result int NOT NULL DEFAULT 0,PRIMARY KEY ( id ))select result, count(*) from toss grou…

pythonweb管理电脑_Python远程控制局域网计算机网络远程控制软件Python的开发,python,电脑,web...

[Python] 纯文本查看 复制代码import web import osimport timefrom PIL import ImageGrabimport numpy as npimport cv2urls (/reboot_html/(.*), reboot_html,/jp_html/(.*), jp_html,/shutdown_html/(.*), shutdown_html,/(js|css|images)/(.*), static)app web.applicati…

ctf的php,CTF中常见的PHP漏洞

1.MD5()漏洞php在处理字符串时会利用&#xff01;&#xff0c;||&#xff0c;进行hash值的比较 他把每一个“0E’开头的哈希值都解释为0&#xff0c;因此如果两个不同的密码经过hash处理之后都是以‘0e’开头&#xff0c;那么PHP会认为两者是相同的&#xff0c;南京邮电大学一次…

php ob 缓存,php中ob函数缓冲机制深入理解

下面就php中ob函数缓冲机制通过文字说明加代码分析的形式给大家展示如下&#xff1a;对于一个刚刚入门的php程序员来说&#xff0c;php缓冲区是几乎透明的。在他们心目中&#xff0c;一个echo print_r 函数&#xff0c;数据便会‘嗖的一声飞到浏览器上&#xff0c;显示出来。我…

php极光推送教程,laravel框架使用极光推送消息操作示例

本文实例讲述了laravel框架使用极光推送消息。分享给大家供大家参考&#xff0c;具体如下&#xff1a;最近需要使用极光推送往客户端推消息&#xff0c;所以这里记录下使用过程。极光推送的服务端文档&#xff1a;https://docs.jiguang.cn/jpush/server/push/server_overview/极…

php 强制刷新,web端实现后退强制刷新功能代码

本文主要和大家介绍了微信web端后退强制刷新功能的实现代码,需要的朋友可以参考下&#xff0c;希望能帮助到大家。具体代码如下所示&#xff1a;//生成uuidvar uuidChars "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");fu…

php强制cookies,php Cookies操作类(附源码)

本cookies操作类的功能&#xff0c;包括&#xff1a;1&#xff0c;保存&#xff0c;读取&#xff0c;更新&#xff0c;清除cookies数据。2&#xff0c;可设置前缀。3&#xff0c;强制超时控制。4&#xff0c;cookies数据可以是字符串&#xff0c;数组&#xff0c;对象等。1&…

php 缩略图 失真,WORDPRESS缩略图失真变形模糊的解决方法

众所周知&#xff0c;网站最怕改版&#xff0c;其中一个主要的原因就是缩略图的问题&#xff0c;旧模板的缩略图尺寸不一定适合新版的模板缩略图尺寸要求&#xff0c;尽管后台的设置-多媒体-缩略图尺寸修改了&#xff0c;可这是新上传的图片才会生成新的尺寸的缩略图&#xff0…

php表单 提交数据,PHP表单提交数据

1.PHP表单处理PHP 超全局变量 $_GET 和 $_POST 用于收集表单数据GET 和 POST 都创建数组(例如&#xff0c;array( key > value, key2 > value2, key3 > value3, ...))。此数组包含键/值对&#xff0c;其中的键是表单控件的名称&#xff0c;而值是来自用户的输入数据。…

binarysearch java,java数据结构之二分查找法 binarySearch的实例

java数据结构之二分查找法 binarySearch的实例折半查找法&#xff0c;前提是已经排好序的数组才可查找实例代码&#xff1a;public class BinarySearch {int[] bArr;public void setArr(int[] bArr){this.bArrbArr;}public static void main(String[] args) {int arrLength16;i…

matlab dotline,基于模糊控制的路径规划算法的仿真实现---Matlab程序.rar

【实例简介】与 本人博客中的课程论文《基于模糊控制的路径规划算法的仿真实现》相配套&#xff0c;可以相互参阅【实例截图】【核心代码】基于模糊控制的路径规划算法的仿真实现---Matlab程序├── fuzzy4│ ├── CheckIsBlocked.asv│ ├── CheckIsBlocked.m│ ├…

php重定义地址栏url,thinkphp框架实现路由重定义简化url访问地址的方法分析

本文实例讲述了thinkphp框架实现路由重定义简化url访问地址的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;如果按照正常访问的话&#xff0c;则需要输入一长串的url地址&#xff0c;这样会显得十分冗长&#xff0c;我可以可以通过对路由规则的重新定义简化url访…

php 数组 json字段去不全,json_encode – PHP给出了不完整的json字符串

首先我的环境&#xff1a;PHP 5.3.2 – 使用Suoshin和xCache的lighttpd / 1.4.26我的代码太多了,不能在这里发布.我会说出来的.文件x.php正在加载一些PHP – Classe,初始化它们,执行一些函数 – >获取Result数组.如果我print_r这个数组我得到一个完整的结果.但是我使用json_…

java 判断季节,Java-用switch判断季节

import java.util.*;class Demo3{public static void main(String[] args){//需求 &#xff1a;输入一个月份 &#xff0c;判断月份属于哪一个季节 &#xff1a;春天:3,4,5//夏天 &#xff1a;6&#xff0c;7&#xff0c;8 &#xff0c;秋天:9,10,11 冬天&#xff1a;12&#x…