kill -l可以看到信号列表

列表

kill -9 pid 可以直接杀死pid的进程,不过这种方式太暴力了。可能会出现:

请求丢失:内存队列中等待执行请求丢失

数据丢失:处于内存缓存中数据未持久化到磁盘

文件损坏:正在写的文件没有没有更新完成,导致文件损坏

业务中断:处理一半的业务被强行中断,如支付成功了,却没有更新到数据库中

服务未下线:上游服务依然往停止节点发送请求

java中存在着优雅停机,靠的是shutdownhook钩子。例如:

Runtime
.getRuntime()
.addShutdownHook(
new Thread(() -> System.out.println("Do something in Shutdown Hook")));

linux中可使用kill -15 发送SIGTERM信号,

去尝试杀死进程,如果过一段时间,进程还没停止,kill -9有出场机会。kill默认信号值就是15。

常用的信号,还有SIGQUIT,也就是kill -3。

在Java程序下,kill -3的输出特别有意思,它直接在stdout上输出了jstack命令所产生的内容。如果是tomcat,那么输出就在canalina.out文件里。

如果jstack对你的应用不好使了,或者应用几乎没有响应了。使用kill -3是一种曲线救国的方式。

其实是JDK屏蔽了这个信号,对Java来说是一个福利。我们在JDK的文档中找到相关介绍。

Sun’s JVM catches signals to implement shutdown hooks for abnormal JVM termination. The JVM uses SIGHUP, SIGINT, and SIGTERM to initiate the running of shutdown hooks.
The JVM uses a similar mechanism to implement the pre-1.2 feature of dumping thread stacks for debugging purposes. Sun’s JVM uses SIGQUIT to perform thread dumps.

以下脚本可以优雅停机,能够接受两个参数。第一个参数是pid,第二个参数是等待的秒数:

pid=$1
count=$2
n=0
if [ ! -n $count ];then
count=10
fi
while [[ $n  -lt  $count ]]
do
let "n++"
kill -0 $pid
if [ $? -ne 0 ]
then
echo "program not exist"
break
else
echo "send kill -15 to$pid"
kill -15 $pid
sleep 1
fi
if [[ $n  -eq $count ]]
then
echo "kill -9$pid"
# after 10s , try to send kill -9
kill -9 $pid
fi
done

脚本将持续使用kill -0判断进程是否存在,然后持续发送kill -15指令。等超过指定的秒数,进程依然存在,则最终发送kill -9命令。