「kill -9」一時爽,秋後算帳淚兩行

原創:小姐姐味道(微信公衆號ID:xjjdog),歡迎分享,轉載請保留出處。任何不保留此聲明的轉載都是抄襲。java

kill是殺死的意思,帶有主動的意味。鑑於masterslave這樣的名詞,須要在計算機軟件中進行整改,kill這樣明顯帶有負面信息的單詞,按理說也須要被幹掉。程序員

不過,若是把命令名字改了,效果也許會更好。由於在Linux上,kill根本就不是殺死的意思。數據庫

它只是想要給進程發送一個信號而已。使用kill -l能夠看到長長的信號列表。緩存

對Java程序員來講,用的最多的就是kill -9,我也不知道從哪裏來的傳承,碼農們都喜歡這種暴力性的命令--喜歡用鋒利的匕首一擊致命。tomcat

可是這種玩法又危險的多,不給進程說話的機會。bash

你們都知道電視劇裏,重要人物臨死的時候,會囉囉嗦嗦說不少話,話說不完是不會死的。不管是武林高手,仍是達官貴人,都得交代一些能讓故事情節繼續發展下去的廢話。微信

《水滸傳》裏的「英雄們」,來的就相對直接一些。看的不爽,直接單刀直入切中要害,不容許他人有一丁點的廢話,一般狀況下直接嗝屁。架構

各位使用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,歡迎添加好友,​進一步交流。​

相關文章
相關標籤/搜索