shutdown-hook
- 建议加上shutdown的钩子
- 如果程序出现了内存溢出crash 则现在代码是没有任何保护措施的
- 或者说运维不小心关闭了服务器等
- 或者运维不小心kill了游戏服务器进程等
- 无法避免kill -9
- 时机
- 程序正常退出
- 使用System.exit()
- 终端使用Ctrl+C触发的中断
+ 系统关闭
- OutOfMemory宕机
- 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)
kill
- kill默认信号是SIGTERM
- kill -9
- kill -2
- SIGINT interrupt 中断信号
- 同ctrl-c
- kill -1
- kill -3
- 只有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);
}
}
}
- 测试步骤
- 其他
- 只有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 this.