Linux下如何正确地kill java进程

Linux下如何正确地kill java进程,第1张

多数人可能会回答 kill -9 pid,这是一种在多数情况下正确的做法。不过本文打算阐述使用kill -9带来的一些问题,并给出另一种标准的kill方式。

标准中断信号

在Linux信号机制中,存在多种进程中断信号(Linux信号列表 )。其中比较典型的有 SIGNKILL(9) 和 SIGNTERM(15).

SIGNKILL(9) 和 SIGNTERM(15) 的区别在于:

SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。

SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。

由此可见,SIGNTERM(15) 才是理论上标准的kill进程信号。

SIGNKILL(9) 带来的问题

先看一段程序

在Linux远程运行JAR包时,是不能关掉窗口程序的,否则程序也会终止。其中nohup表示后台运行,关闭窗口后也也继续执行,&意思是终端连接的时候后台运行,终端断了进程也会停。

具体解决方法是使用nohup命令,在窗口程序的前面加上nohup,程序的后面加上&,这样程序就会一直执行直到结束,而不会因为关闭窗口程序而停了。

例子,比如:nohupphpspider.php&回车,然后提示一堆东西,再次回车,回到shell界面。这就可以了。

还有一个问题:程序在执行中会输出一些信息,如果后台执行的话,这些信息是不是没法看了?(比如:程序执行出错终端,想看看报错信息之类的)。使用了nohup命令后,会在当前目录下生成一个nohup.out的日志文件,记录的就是命令的输出。

首先,这段shell应该有start和stop的功能。如何stop当前我想停止的进程在Linux下有很多方法,我用的方法是,启动时将进程对应的process id记录到一个文件中,在停止这个进程时,从文件中读取process id进行kill。同时,做一个crontab,不停在系统中查找文件中的process id对应的进程是否存在,如果不存在,重新启动该进程。

启动和停止脚本:ctrl.sh

Shell代码

#!/bin/sh

#

# start/stop the Service

#

# do some init here

#

case "$1" in

'restart')

# first Stopping the Service

PID=`sed -n 1p pidfile` #get pid from file

if [ ! -z "$PID" ] then

echo "Stopping the Service, begin killing ${PID}"

kill ${PID} >/dev/null 2>&1

sleep 2

fi

# second Starting the Service

if [ some condition here ]then

echo "Starting the Service"

java -classpath some_class_path_here -jar helloworld.jar &

echo $! >pidfile #record process id to file

fi

'stop')

# Stopping the Service

PID=`sed -n 1p pidfile` #get pid from pidfile

if [ ! -z "$PID" ] then

echo "Stopping the Service, begin killing ${PID}"

kill ${PID} >/dev/null 2>&1

fi

*)

echo "Unmarkable usage: $0 {restart|stop}"

esac

然后再做一个crontab需要执行的脚本:crntb.sh

Shell代码

#!/bin/sh

PID=`sed -n 1p pidfile`

cmd=`ps -e|grep $PID`#get process with the given pid

indx=`expr index "$cmd" "java"` #whether the string 'cmd' contains 'java'

if [ "$indx" = "0" ]then

/...path of ctrl.sh.../ctrl.sh restart

fi

最后在crontab中每分钟执行上面的crntb.sh

Shell代码

crontab -e

Shell代码

0-59 * * * * * /....path of crntb.sh.../crntb.sh

这样就可以每分钟查看当前pid对应的进程是不是还在,如果不在了,就重新启动。

当然,光用这几小段代码是不足以维护一个完整的商用程序的。但是,做到了这点,最起码万里长征的第一步已经迈出去了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12028141.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存