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命令。