11

“kill -9”一时爽,秋后算账泪两行

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA4MTc4NTUxNQ%3D%3D&%3Bmid=2650521465&%3Bidx=1&%3Bsn=a49227c22bab1e68b7b6e6778053c9b9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

e6JBVrU.gif

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。任何不保留此声明的转载都是抄袭。

kill 是杀死的意思,带有主动的意味。鉴于 masterslave 这样的名词,需要在计算机软件中进行整改,kill这样明显带有负面信息的单词,按理说也需要被干掉。

不过,如果把命令名字改了,效果也许会更好。因为在Linux上, kill 根本就不是杀死的意思。

它只是想要给进程发送一个信号而已。使用 kill -l 可以看到长长的信号列表。

b26NFfz.png!web

对Java程序员来说,用的最多的就是 kill -9 ,我也不知道从哪里来的传承,码农们都喜欢这种暴力性的命令--喜欢用锋利的匕首一击致命。

但是这种玩法又危险的多,不给进程说话的机会。

大家都知道电视剧里,重要人物临死的时候,会啰啰嗦嗦说很多话,话说不完是不会死的。无论是武林高手,还是达官贵人,都得交代一些能让故事情节继续发展下去的废话。

《水浒传》里的“英雄们”,来的就相对直接一些。看的不爽,直接单刀直入切中要害,不允许他人有一丁点的废话,通常情况下直接嗝屁。

各位使用 kill -9 的兄弟们,个个都像黑黑的李逵,单纯、暴力、不讲人情。

SIGKILL
9
Kill signal
结束信号

中国的中庸太极之道,在此荡然无存。 kill -9 直接使得 优雅关闭 这个名词成了废物。

何为优雅关闭?其实就像是人的“遗言”,要在死之前,交代一些身后事。

我就常常在想,在我死之前,要把所有的钱花的一分不剩。既不留给后代,也不让它烂在银行里。这就需要做很多事。

计算机软件中,在死之前,要处理的事情也还不少。比如,需要把缓冲区的内容处理完毕,发送出去;微服务节点需要先把自己从注册中心摘除,才能放心的 go die

大体来说,有下面几个影响:

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

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

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

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

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

这些情况下,如果把服务玩坏了,正好被领导撞上,被开是分分钟的事。

Java应用中处处充斥着这种 优雅 ,靠的是 shutdownhook 钩子。就是下面这行代码:

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

有没有好的办法?有,用 kill -15 发送 SIGTERM 信号即可。

但有时候 kill -15 并不能杀死进程,这个时候,才是 kill -9 需要出场的时候。

听够了15临死前说的一些废话,使用9要它的命。

一般的,需要使用 kill -15 去尝试杀死进程。如果过一段时间(比如10秒),进程还没有停止, kill -9 才会出场。

kill的默认信号值,就是 15 ,可以说是很贴心了。但还是有很多人使用 9

我想了半天原因,就是一个字:

kill -15 需要多次确认,而 kill -9 一次完事,多数情况下不会出事。有这提高工作效率的事,何乐而不为呢?

常用的信号,还有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 命令。

问题是,通常情况下,你还是需要等待上几秒。自动化机器人不会觉得烦,你会。

所以你还是用 kill -9

作者简介: 小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

后台回复“ 加群 ”,带你进入高手如云交流群

推荐阅读:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK