[转帖]Linux kill & Java shutdownhook

linux,kill,java,shutdownhook · 浏览次数 : 0

小编点评

**ShutdownHook测试代码** ```java public class ShutdownHookTest { public static void main(String[] args) throws Exception { Runtime.getRuntime() .addShutdownHook(new Thread(() -> System.out.println("ShutdownHookTest"))); // 循环运行,等待SIGINT或SIGHUP信号 while (true) { Thread.sleep(5000); } } } ``` **测试步骤** 1. 编译和运行程序: ```bash javac ShutdownHookTest.java java ShutdownHookTest ``` 2. 切换到另一个会话,查询进程ID: ```bash jps ``` 3. 使用 `kill -1` 发送 HUP 信号: ```bash kill -1 1729 ``` 4. 使用 `kill -2` 发送 INT 信号: ```bash kill -2 1729 ``` 5. 使用 `kill -3` 发送 SIGQUIT 信号: ```bash kill -3 1729 ``` 6. 使用 `kill -15` 发送 SIGTERM 信号: ```bash kill -15 1729 ``` 7. 使用 `kill -9` 发送 SIGKILL 信号: ```bash kill -9 1729 ``` 8. 使用 `kill -2` 中断后台进程: ```bash kill -2 1729 ``` 9. 使用 `kill -1` 中断前台进程: ```bash kill -1 1729 ``` 10. 使用 `kill` 命令以 `&` 开启进程,并使用 `kill` 命令中断: ```bash & kill 1729 ``` 11. 使用 `screen` 或 `tmux` 等工具进入终端并执行 `exit` 命令。

正文

https://www.jianshu.com/p/8001a66d37c9

 

shutdown-hook

  • 建议加上shutdown的钩子
    • 如果程序出现了内存溢出crash 则现在代码是没有任何保护措施的
    • 或者说运维不小心关闭了服务器等
    • 或者运维不小心kill了游戏服务器进程等
  • 无法避免kill -9
  • 时机
    • 程序正常退出
    • 使用System.exit()
    • 终端使用Ctrl+C触发的中断
      + 系统关闭
    • OutOfMemory宕机
    • 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)

kill

  • kill默认信号是SIGTERM
    • 15 终止信号
  • kill -9
    • SIGKILL kill信号
  • kill -2
    • SIGINT interrupt 中断信号
    • 同ctrl-c
  • kill -1
    • SIGHUP hang up 挂起信号
  • kill -3
    • SIGQUIT 可打印进程#线程堆栈
  • 只有kill -9能够结束jvm进程,别的信号量只是发送给java进程处理,至于如何响应是程序代码决定的
    • SIGTERM是不带参数时kill发送的信号,意思是进程终止运行,但执行与否还得看进程是否支持.如果进程还没有终止,可以使用 kill -SIGKILL pid,这是由内核来终止进程,进程不能监听这个信号
    • Java程序如果添加了shutdownhook,则可以监听1/2/15

linux

  • screen
  • SIGHUP与nohup
    • 当用户启动一个进程的时候,这个进程是运行在前台,使用与相应控制终端相联系的标准输入、输出进行输入和输出。即使将进程的输入输出重定向,并将进程放在后台执行,进程仍然和当前终端设备有关系。正因为如此,在当前的登录会话结束时,控制终端设备将和登录进程相脱离,那么系统就向所有与这个终端相联系的进程发送SIGHUP的信号,通知进程线路已经挂起了,如果程序没有接管这个信号的处理,那么缺省的反应是进程结束。因此普通的程序并不能真正脱离登录会话而运行进程,为了使得在系统登录后还可以正常执行,只有使用命令nohup来启动相应程序

测试kill与Java#shutdownhook与nohup

  • 主要测试比较不常见的kill#-1,#-2,#-3选项
  • 测试代码
public class ShutdownHookTest {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime()
                .addShutdownHook(new Thread(() -> System.out.println("ShutdownHookTest")));

        while (true) {
            Thread.sleep(5000);
        }
    }
}
  • 测试步骤
    • $ javac javac ShutdownHookTest.java // 编译,生成.class
    • $ java ShutdownHookTest // 前台运行
    • $ jps // 切换到另一个session,查询进程pid
    • $ kill -1 1729 // 使用kill -1 发出HUP的信号
      • 进程结束
      • 控制台输出:ShutdownHookTest 即钩子可监听SIGHUP(1)
      • 解释:因为进程本身就是非nohup运行 则HUP信号直接结束该进程(可参考nohup命令)
        • 如果用nohup启动(会忽略SIGHUP信号) 则kill -1则无效 即进程没有结束
        • 因为进程没结束 所以也不会执行shutdownhook
    • $ kill -2 1729 // 使用kill -2 发出INTTERUPT中断信号
      • 控制台输出:ShutdownHookTest 即钩子可监听SIGINT(2)
      • 进程退出的原因是发送了一个中断信号,而我们的Java程序核心逻辑是sleep,sleep被中断,进程结束
        • 只能中断前台进程
        • 如果我们是用nohup & 启动,即后台进程则无法中断
        • nohup表示忽略SIGHUP &表示后台进程
    • $ kill -3 1729 // 使用kill -3 发出SIGQUIT信号
      • 直接打印出了进程#线程堆栈
          2017-09-01 15:38:29
          Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.40-b25 mixed mode):
          ...
      
      • 即该命令可以直接打印进程的线程堆栈信息(又多了一个技能包) 前台进程也没有结束
      • 如果是用nohup启动的 则默认会将线程堆栈信息写入nohup.out
        • 如果你将nohup日志重定向到了/dev/null 则无法看到输出
    • $ kill -15 1729 // 使用kill -15 发出SIGTERM信号 终止信号(15是kill的默认信号)
      • 控制台输出:ShutdownHookTest 即钩子可监听SIGTERM
      • 进程退出 原因同 -2
      • 前台进程和后台进程都可终止
    • $ kill -9 1729 // 使用kill -9 发出SIGKILL信号 kill信号
      • 控制台直接显示Killed字样 shutdownhook的输出没有执行
      • 进程退出
      • 即钩子无法监听9
  • 其他
    • 只有kill -9能够结束jvm进程,别的信号量只是发送给java进程处理,至于如何响应是程序代码决定的
    • kill -3 可以打印线程堆栈
    • kill -1 对于nohup启动的进程无法终止,因为nohup忽略该信号
    • kill -2 中断前台进程
    • kill -15 前后台进程都可以终止
    • kill -9 死亡kill
    • shell中使用& 可避免终端关闭因SIGHUP信号而终止
      • 非nohup & 可使用kill -1 或者kill -15 或者kill终止
      • 不能使用kill -2终止,因为&表示后台进程 无法关闭
    • 即kill -1/-2/-15 SIGHUP/SIGINT/SIGTERM 都可以将进程关闭
    • 而Java的shutdownhook也恰恰可以监听1/2/15
    • 归根结底,关服最稳妥的方法就是,用http触发关服方法,同时在钩子里也触发这个方法,业务中关服了开服需要继续的,业务单独实现入库
  • 其他测试
    • 如果我们的程序的主逻辑是一个等待标准输入的逻辑
      • 1/2/15都可以终止程序
      • ctrl+c也可以终止
      • 如果直接用nohup启动的话则会直接抛出异常
        • If standard input is associated with a terminal, the nohup utility may redirect standard input from an unspecified file.
        • standard input get redirected from /dev/null by nohup
        • 关闭标准输入 该进程不再能够接收任何输入,即使运行在前台
        • nohup命令安排来自/dev/null的输入,并且输出和错误都可以转到nohup.out
      • 当前与终端交互的进程称为前台进程组,其余进程组称为后台进程组
      • 相对而言nohup占用资源更少,没有交互需求的时候,nohup就能满足需要了
        • !! 如果需要交互逻辑需要用screen/tmux
    • jvm有一个-Xrs的参数(reduce signal),用来忽略系统信号
  • ref
  • 扩展-why nohup redirect stanard input
    Historical versions of nohup did not affect standard input, but that causes problems in the common scenario where the user logs into a system, types the command:
    
    nohup make &
    
    at the prompt, and then logs out. If standard input is not affected by nohup, the login session may not terminate for quite some time, since standard input remains open until make exits. To avoid this problem, POSIX.1-2008 allows implementations to redirect standard input if it is a terminal. Since the behavior is implementation-defined, portable applications that may run into the problem should redirect standard input themselves. For example, instead of:
    
    nohup make &
    
    an application can invoke:
    
    nohup make </dev/null &
The redirection of stdin for nohup is entirely optional as nohup will usually redirect it to </dev/null if it was a terminal, to avoid the terminal not being able to close when you type exit. You can do your own 0< redirection, to /dev/null or a file, to avoid

与[转帖]Linux kill & Java shutdownhook相似的内容:

[转帖]Linux kill & Java shutdownhook

https://www.jianshu.com/p/8001a66d37c9 shutdown-hook 建议加上shutdown的钩子 如果程序出现了内存溢出crash 则现在代码是没有任何保护措施的 或者说运维不小心关闭了服务器等 或者运维不小心kill了游戏服务器进程等 无法避免kill -9

[转帖]某游戏海外版本堆外内存泄露排查

https://www.jianshu.com/p/cae00d9c99fe 某游戏海外版本堆外内存泄露排查 现象 线上有部分服务器用top发现Java进程内存占用占比达到99,而且出现了有一个服务器被Linux OOM Kill 排查 选择了110服,该机器的Java进程最大堆内存设置的是9710

[转帖]linux 上进程被随机kill掉,如何监测和查询;谁杀了我的进程;Who sends a SIGKILL to my process mysteriously on ubuntu server

https://www.cnblogs.com/xuyaowen/p/linux-audit.html 今天跑实验,发现进程被随机kill。咨询了服务器上的其他同学,他们说之前也发生过,一直存在。看来可能有可能不是我自己程序的原因,只能自己动手解决了。 在 Who sends a SIGKILL t

[转帖]kill及kill -9的用法及如何实现进程的优雅退出

1. kill与signals 我们这里所说的kill是指作为shell command的那个kill(相对地,linux 系统中还有个叫做kill的system call, man 2 kill可查看其功能及用法),shell终端中输入man kill可以看到,kill的作用是向某个指定的进程或进

[转帖]nginx中用到的kill命令

1、kill命令 1.1、kill命令简介 我们都知道,想要在Linux中终止一个进程有两种方式,如果是前台进程可以使用Ctrl+C键进行终止;如果是后台进程,那么需要使用kill命令来终止。(其实Ctrl+C也是kill命令)。 kill命令的格式是: kill -signal pid 其中 pi

[转帖]Linux 磁盘I/O 调度算法 说明

2022-08-23 13:031361转载Linux 1 Linux 4.0 IO协议栈框架图 I/O 调度算法在各个进程竞争磁盘I/O的时候担当了裁判的角色。他要求请求的次序和时机做最优化的处理,以求得尽可能最好的整体I/O性能。 Linux 4.0 IO协议栈框架图 I/O调度程序的总结 当向

[转帖]Linux中常见IO调度器

https://www.jianshu.com/p/3c16e39a005a 单队列调度算法多队列调度算法 deadline mqdeadlines cfq bfq noop none kyber 对于磁盘I/O,Linux提供了cfq, deadline和noop三种调度策略 cfq: 这个名字是

[转帖]Linux 平台使用shc 工具加密shell 脚本

2021-08-03 20:4510030原创Linux 本文链接:https://www.cndba.cn/dave/article/4642 1 shc 工具说明 shell 脚本是常用脚本,运维中经常使用,但有时候在shell 脚本中会包含一些敏感的信息,比如密码或者特殊的参数,此时我们就可以

[转帖]Linux系统多网卡环境下的路由配置

https://www.cnblogs.com/connect/p/linux-static-route.html Linux下路由配置命令 1. 添加主机路由 route add -host 192.168.1.11 dev eth0 route add -host 192.168.1.12 gw

[转帖]linux命令行下如何格式化json并进行各种json处理操作

https://blog.csdn.net/penriver/article/details/122016563 有时需要在linux 的命令行下,需要查看json的内容或针对json进行各种操作,本文针对此进行梳理、总结。 在Linux系统下基于python json.tool可以格式化json,