Java应用通过操作系统SIGTERM信号触发JVM标准退出流程,由Shutdown Hook执行清理,而非直接使用System.exit;现代JDK内置信号响应机制,无需手动注册SignalHandler;部署时应依赖标准信号机制并正确实现Shutdown Hook。
Java 应用在部署中不直接靠 System.exit 响应信号量退出,而是通过操作系统信号(如 SIGTERM)触发 JVM 的标准退出流程,再由 Shutdown Hook 完成清理——System.exit 本身不“监听”信号,它只是退出动作的其中一种触发源。
Linux/Unix 系统中,运维常用 kill -15 <pid>(即发送 SIGTERM)通知 Java 进程优雅关闭。JVM 内部会将该信号转化为等效的 System.exit(143)(注意:143 是 SIGTERM 的常见退出码,但非强制),进而启动 Shutdown Hook 执行序列。
SIGTERM 的响应,无需手动注册 SignalHandler(该 API 已被标记为 deprecated,且行为不稳定)SIGTERM 后,JVM 自动开始 shutdown 序列,与调用 System.exit(0) 触发的流程完全一致sun.misc.Signal)兼容性差、易出错,且可能干扰 JVM 原生信号处理容器化或 systemd 管理的场景下,应依赖标准信号机制,而非在业务代码里硬编码 System.exit:
SIGTERM(默认),等待 grace period 后再发 SIGKILL;应用只需注册 Shutdown Hook,无需干预信号接收KillSignal=SIGTERM 和 TimeoutStopSec=30,确保有足够时间执行钩子spring.lifecycle.timeout-per-shutdown-phase=30s,配合 Actuator 的 /actuator/shutdown(本质也是触发 System.exit 或上下文关闭)所有退出路径(System.exit、Ctrl+C、kill -15、系统关机)最终都汇入同一套钩子执行逻辑:
立即学习“Java免费学习笔记(深入)”;
Runtime.getRuntime().addShutdownHook(new Thread(...)) 注册清理任务部署稳定性高度依赖退出路径的可控性,以下操作会破坏优雅停机:
System.exit:可能导致部分请求正在处理时被强杀,订单/支付状态不一致kill -9 强制终止:绕过所有钩子和清理逻辑,必然导致资源泄漏、数据丢失、文件损坏System.exit 或启动新线程:可能引发死锁或未定义行为System.exit 或 SIGTERM 下根本不会执行