偶尔会碰到用SecureCRT在shell启动java进程并后台运行(命令最后加&)的时候, 因为断电死机等原因断开shell, 然后进程被结束了. 运维大佬也说用他们的工具启动进程后一断开连接进程就结束了.
后来查到是因为shell在断开的时候会向在当前shell启动的后台进程发送SIGHUP信号, 导致进程结束, 大概是这样, 具体什么条件才会发送SIGHUP没有仔细研究.
解决方法 (用以下两种方法之一即可):
1 启动进程的时候加上nohup
nohup java ... </dev/null >/dev/null 2>&1 &
2 在代码里面设置忽略SIGHUP信号
String osName = System.getProperty("os.name");
if (osName != null && osName.toLowerCase().startsWith("linux")) {
// 防止进程在后台时因为shell断开被杀死
Signal.handle(new Signal("HUP"), signal -> {
System.out.println("receive SIGHUP");
});
}
用第二种方法的时候, 启动进程参数中不能有-Xrs, 否则不生效
-Xrs
Disables signal handling in the JVM.