日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
老板:kill-9的原理都不知道就敢到線上執(zhí)行,明天不用來了!

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

目前創(chuàng)新互聯(lián)已為上千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站運營、企業(yè)網(wǎng)站設(shè)計、青陽網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

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

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

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

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

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

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

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

kill 命令

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

kill命令的格式是:

 
 
 
  1. kill[參數(shù)][進程號] 
  2.  
  3. 如: 
  4.  
  5. kill 21121 
  6.  
  7. kill -9 21121 

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

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

  • -l 信號,若果不加信號的編號參數(shù),則使用“-l”參數(shù)會列出全部的信號名稱
  • -a 當(dāng)處理當(dāng)前進程時,不限制命令名和進程號的對應(yīng)關(guān)系
  • -p 指定kill 命令只打印相關(guān)進程的進程號,而不發(fā)送任何信號
  • -s 指定發(fā)送信號
  • -u 指定用戶

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

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

  • HUP 1 終端斷線
  • INT 2 中斷(同 Ctrl + C)
  • QUIT 3 退出(同 Ctrl + \)
  • TERM 15 終止
  • KILL 9 強制終止
  • CONT 18 繼續(xù)(與STOP相反, fg/bg命令)
  • STOP 19 暫停(同 Ctrl + Z)

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

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

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

kill命令默認的信號就是15,首先來說一下這個默認的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)的進程要進行"安全、干凈的退出",程序接到信號之后,退出前一般會進行一些"準(zhǔn)備工作",如資源釋放、臨時文件清理等等,如果準(zhǔn)備工作做完了,再進行程序的終止。

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

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

和kill -15相比,kill -9就相對強硬一點,系統(tǒng)會發(fā)出SIGKILL信號,他要求接收到該信號的程序應(yīng)該立即結(jié)束運行,不能被阻塞或者忽略。所以,相比于kill -15命令,kill -9在執(zhí)行時,應(yīng)用程序是沒有時間進行"準(zhǔn)備工作"的,所以這通常會帶來一些副作用,數(shù)據(jù)丟失或者終端無法恢復(fù)到正常狀態(tài)等。

Java是如何處理SIGTERM(15)的

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

正常關(guān)閉:當(dāng)最后一個非守護線程結(jié)束或者調(diào)用了System.exit或者通過其他特定平臺的方法關(guān)閉(接收到SIGINT(2)、SIGTERM(15)信號等)強制關(guān)閉:通過調(diào)用Runtime.halt方法或者是在操作系統(tǒng)中強制kill(接收到SIGKILL(9)信號)異常關(guān)閉:運行中遇到RuntimeException異常等。

JVM進程在接收到kill -15信號通知的時候,是可以做一些清理動作的,比如刪除臨時文件等。當(dāng)然,開發(fā)者也是可以自定義做一些額外的事情的,比如讓tomcat容器停止,讓dubbo服務(wù)下線等。而這種自定義JVM清理動作的方式,是通過JDK中提供的shutdown hook實現(xiàn)的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注冊一個JVM關(guān)閉的鉤子。例子如下:

 
 
 
  1. package com.hollis; 
  2.  
  3.  
  4. public class ShutdownHookTest { 
  5.  
  6.  
  7.     public static void main(String[] args) { 
  8.  
  9.         boolean flag = true; 
  10.  
  11.         Runtime.getRuntime().addShutdownHook(new Thread(() -> { 
  12.  
  13.             System.out.println("hook execute..."); 
  14.  
  15.         })); 
  16.  
  17.  
  18.         while (flag) { 
  19.  
  20.             // app is runing 
  21.  
  22.         } 
  23.  
  24.  
  25.         System.out.println("main thread execute end..."); 
  26.  
  27.     } 
  28.  

執(zhí)行命令:

 
 
 
  1.  jps 
  2.  
  3. 6520 ShutdownHookTest 
  4.  
  5. 6521 Jps 
  6.  
  7.  kill 6520 

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

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

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

 
 
 
  1.  kill -9 6520 

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

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

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

總結(jié)

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

kill -15執(zhí)行時,系統(tǒng)向?qū)?yīng)的程序發(fā)送SIGTERM(15)信號,該信號是可以被執(zhí)行、阻塞和忽略的,所以應(yīng)用程序接收到信號后,可以做一些準(zhǔ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)機等足夠的時間進行收尾。

關(guān)于作者:Hollis(ID:hollischuang),一個對Coding有著獨特追求的人,現(xiàn)任阿里巴巴技術(shù)專家,個人技術(shù)博主,技術(shù)文章全網(wǎng)閱讀量數(shù)千萬,《程序員的三門課》聯(lián)合作者。

【本文是專欄作者Hollis的原創(chuàng)文章,作者微信公眾號Hollis(ID:hollischuang)】


新聞名稱:老板:kill-9的原理都不知道就敢到線上執(zhí)行,明天不用來了!
網(wǎng)頁路徑:http://m.5511xx.com/article/dhdjppo.html