日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

老板:kill -9的原理都不知道就敢到线上执行,明天不用来了!

發(fā)布時間:2025/3/21 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 老板:kill -9的原理都不知道就敢到线上执行,明天不用来了! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

相信很多程序員對于Linux系統(tǒng)都不陌生,即使自己的日常開發(fā)機(jī)器不是Linux,那么線上服務(wù)器也大部分都是的,所以,掌握常用的Linux命令也是程序員必備的技能。

但是,怕就怕很多人對于部分命令只是一知半解,使用不當(dāng)就能導(dǎo)致線上故障。

前段時間,我們的線上應(yīng)用報警,頻繁FGC,需要緊急處理問題,于是有同事去線上重啟機(jī)器(正常程序應(yīng)該是先采集堆dump,然后再重啟,方便排查是否存在內(nèi)存泄露等問題)。

但是在重啟過程中,同事發(fā)現(xiàn)正常的重啟命令應(yīng)用無反應(yīng),然后嘗試使用kill命令"殺"掉Java進(jìn)程,但是仍然無效。于是他私自決定使用 "kill -9"結(jié)束了進(jìn)程的生命。

雖然應(yīng)用進(jìn)程被干掉了,但是隨之而來帶來了很多問題,首先是上游系統(tǒng)突然發(fā)生大量報警,對應(yīng)開發(fā)找過來說調(diào)用我們的RPC服務(wù)無響應(yīng),頻繁超時。

后來,我們又發(fā)現(xiàn)系統(tǒng)中存在部分臟數(shù)據(jù),有些在同一個事務(wù)中需要完整更新的數(shù)據(jù),只更新了一半…

為什么正常的kill無法"殺掉"進(jìn)程,而kill -9就可以?為什么kill -9會引發(fā)這一連串連鎖反應(yīng)?正常的kill執(zhí)行時,JVM會如何處理的呢?

要搞清楚這些問題,我們要先從kill命令說起。

kill?命令

我們都知道,想要在Linux中終止一個進(jìn)程有兩種方式,如果是前臺進(jìn)程可以使用Ctrl+C鍵進(jìn)行終止;如果是后臺進(jìn)程,那么需要使用kill命令來終止。(其實Ctrl+C也是kill命令)

kill命令的格式是:

kill[參數(shù)][進(jìn)程號] 如: kill?21121 kill?-9?21121

其中[參數(shù)]是可選的,進(jìn)程號可以通過jps/ps/pidof/pstree/top等工具獲取。

kill的命令參數(shù)有以下幾種:

-l 信號,若果不加信號的編號參數(shù),則使用“-l”參數(shù)會列出全部的信號名稱

-a 當(dāng)處理當(dāng)前進(jìn)程時,不限制命令名和進(jìn)程號的對應(yīng)關(guān)系

-p 指定kill 命令只打印相關(guān)進(jìn)程的進(jìn)程號,而不發(fā)送任何信號

-s 指定發(fā)送信號

-u 指定用戶

通常情況下,我們使用的-l(信號)的時候比較多,如我們前文提到的kill -9中的9就是信號。

信號如果沒有指定的話,默認(rèn)會發(fā)出終止信號(15)。常用的信號如下:

HUP 1 終端斷線

INT 2 中斷(同 Ctrl + C)

QUIT 3 退出(同 Ctrl + \)

TERM 15 終止

KILL 9 強(qiáng)制終止

CONT 18 繼續(xù)(與STOP相反, fg/bg命令)

STOP 19 暫停(同 Ctrl + Z)

比較常用的就是強(qiáng)制終止信號:9和終止信號:15,另外,中斷信號:2其實就是我們前文提到的Ctrl + C結(jié)束前臺進(jìn)程。

那么,kill -9?和?kill -15到底有什么區(qū)別呢?該如何選擇呢?

kill -9 和 kill -15的區(qū)別

kill命令默認(rèn)的信號就是15,首先來說一下這個默認(rèn)的kill -15信號。

當(dāng)使用kill -15時,系統(tǒng)會發(fā)送一個SIGTERM的信號給對應(yīng)的程序。當(dāng)程序接收到該信號后,具體要如何處理是自己可以決定的。

這時候,應(yīng)用程序可以選擇:

  • 1、立即停止程序

  • 2、釋放響應(yīng)資源后停止程序

  • 3、忽略該信號,繼續(xù)執(zhí)行程序

因為kill -15信號只是通知對應(yīng)的進(jìn)程要進(jìn)行"安全、干凈的退出",程序接到信號之后,退出前一般會進(jìn)行一些"準(zhǔn)備工作",如資源釋放、臨時文件清理等等,如果準(zhǔn)備工作做完了,再進(jìn)行程序的終止。

但是,如果在"準(zhǔn)備工作"進(jìn)行過程中,遇到阻塞或者其他問題導(dǎo)致無法成功,那么應(yīng)用程序可以選擇忽略該終止信號。

這也就是為什么我們有的時候使用kill命令是沒辦法"殺死"應(yīng)用的原因,因為默認(rèn)的kill信號是SIGTERM(15),而SIGTERM(15)的信號是可以被阻塞和忽略的。

和kill -15相比,kill -9就相對強(qiáng)硬一點,系統(tǒng)會發(fā)出SIGKILL信號,他要求接收到該信號的程序應(yīng)該立即結(jié)束運行,不能被阻塞或者忽略。

所以,相比于kill -15命令,kill -9在執(zhí)行時,應(yīng)用程序是沒有時間進(jìn)行"準(zhǔn)備工作"的,所以這通常會帶來一些副作用,數(shù)據(jù)丟失或者終端無法恢復(fù)到正常狀態(tài)等。

Java是如何處理SIGTERM(15)的

我們都知道,在Linux中,Java應(yīng)用是作為一個獨立進(jìn)程運行的,Java程序的終止運行是基于JVM的關(guān)閉實現(xiàn)的,JVM關(guān)閉方式分為3種:

正常關(guān)閉:當(dāng)最后一個非守護(hù)線程結(jié)束或者調(diào)用了System.exit或者通過其他特定平臺的方法關(guān)閉(接收到SIGINT(2)、SIGTERM(15)信號等)

強(qiáng)制關(guān)閉:通過調(diào)用Runtime.halt方法或者是在操作系統(tǒng)中強(qiáng)制kill(接收到SIGKILL(9)信號)

異常關(guān)閉:運行中遇到RuntimeException異常等。

JVM進(jìn)程在接收到kill -15信號通知的時候,是可以做一些清理動作的,比如刪除臨時文件等。

當(dāng)然,開發(fā)者也是可以自定義做一些額外的事情的,比如讓tomcat容器停止,讓dubbo服務(wù)下線等。

而這種自定義JVM清理動作的方式,是通過JDK中提供的shutdown hook實現(xiàn)的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注冊一個JVM關(guān)閉的鉤子。

例子如下:

package?com.hollis;public?class?ShutdownHookTest?{public?static?void?main(String[]?args)?{boolean?flag?=?true;Runtime.getRuntime().addShutdownHook(new?Thread(()?->?{System.out.println("hook?execute...");}));while?(flag)?{//?app?is?runing}System.out.println("main?thread?execute?end...");} }

執(zhí)行命令:

??jps 6520?ShutdownHookTest 6521?Jps ??kill?6520

控制臺輸出內(nèi)容:

hook?execute...
Process?finished?with?exit?code?143?(interrupted?by?signal?15:?SIGTERM)

可以看到,當(dāng)我們使用kill(默認(rèn)kill -15)關(guān)閉進(jìn)程的時候,程序會先執(zhí)行我注冊的shutdownHook,然后再退出,并且會給出一個提示:interrupted by signal 15: SIGTERM

如果我們執(zhí)行命令kill -9:

??kill?-9?6520

控制臺輸出內(nèi)容:

Process?finished?with?exit?code?137?(interrupted?by?signal?9:?SIGKILL)

可以看到,當(dāng)我們使用kill -9 強(qiáng)制關(guān)閉進(jìn)程的時候,程序并沒有執(zhí)行shutdownHook,而是直接退出了,并且會給出一個提示:interrupted by signal 9: SIGKILL

總結(jié)

kill命令用于終止Linux進(jìn)程,默認(rèn)情況下,如果不指定信號,kill 等價于kill -15。

kill -15執(zhí)行時,系統(tǒng)向?qū)?yīng)的程序發(fā)送SIGTERM(15)信號,該信號是可以被執(zhí)行、阻塞和忽略的,所以應(yīng)用程序接收到信號后,可以做一些準(zhǔn)備工作,再進(jìn)行程序終止。

有的時候,kill -15無法終止程序,因為他可能被忽略,這時候可以使用kill -9,系統(tǒng)會發(fā)出SIGKILL(9)信號,該信號不允許忽略和阻塞,所以應(yīng)用程序會立即終止。

這也會帶來很多副作用,如數(shù)據(jù)丟失等,所以,在非必要時,不要使用kill -9命令,尤其是那些web應(yīng)用、提供RPC服務(wù)、執(zhí)行定時任務(wù)、包含長事務(wù)等應(yīng)用中,因為kill -9?沒給spring容器、tomcat服務(wù)器、dubbo服務(wù)、流程引擎、狀態(tài)機(jī)等足夠的時間進(jìn)行收尾。

總結(jié)

以上是生活随笔為你收集整理的老板:kill -9的原理都不知道就敢到线上执行,明天不用来了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。