OpenJDK进程崩溃后自动重启需配置systemd服务文件:设Type=simple、Restart=on-failure、RestartSec=10、StartLimitIntervalSec=60与StartLimitBurst=3,并添加MemoryMax、CPUQuota等资源限制及健康检查。

systemd 里怎么让 OpenJDK 进程崩溃后自动重启
OpenJDK 本身不提供进程守护能力,System.exit() 只是终止当前 JVM,是否重启、何时重启、重试几次,全由 systemd 决定。关键不是改 Java 代码,而是配对 .service 文件里的重启策略和熔断参数。
Restart=on-failure 是最常用且安全的起点
它只在进程非零退出(比如 System.exit(1))、被信号杀死(SIGSEGV、SIGKILL)、启动超时或 OOM 被杀时触发重启;而 System.exit(0) 不会重启,适合主动停服场景。
-
Restart=on-failure比always更合理:避免把“正常关闭”误判为故障 - 不要用
forking类型:OpenJDK 启动 jar 通常不 fork 子进程,应设Type=simple,否则 systemd 无法正确跟踪主进程 PID - 若 Java 进程因 OOM 被内核 kill,systemd 默认能捕获并按
on-failure处理——前提是没配错Type或漏掉OOMScoreAdjust
RestartSec 和 StartLimit 必须一起配,否则可能雪崩
光有 Restart=on-failure 不够。服务一崩溃就立刻拉起,容易撞上端口未释放、磁盘 IO 卡顿、依赖服务还没就绪等问题,导致无限循环失败。
-
RestartSec=10:建议设 5–15 秒,给资源释放和依赖恢复留缓冲时间 -
StartLimitIntervalSec=60和StartLimitBurst=3必须成对出现:1 分钟内最多重启 3 次,超限后 systemd 停止尝试并标记为start-limit-hit - 不设熔断时,一次配置错误可能导致每秒拉起新 JVM,迅速耗尽内存和文件描述符
Java 进程“假死”时 systemd 不会干预,得靠额外手段
systemd 只监控进程是否存在,不感知 CPU 占满、线程卡死、HTTP 接口无响应等状态。这时候即使进程还活着,服务已不可用。
- 加健康检查脚本:在
[Service]里写ExecStartPre=/usr/bin/curl -f http://localhost:8080/actuator/health || exit 1(Spring Boot)或类似逻辑 - 限制资源防拖垮:
MemoryMax=2G、CPUQuota=150%、LimitNOFILE=65536 - 配合
WatchdogSec=30+ 应用层心跳(如 Spring Boot Actuator 的/actuator/watchdog),启用Restart=watchdog才能真正覆盖假死场景
最容易被忽略的是 Type=simple 和 StartLimit* 的组合;很多人只加了 Restart=on-failure 就以为万事大吉,结果服务一出问题就高频闪退,日志里全是重复的 Starting… Failed… Starting…,根本看不出原始错误。先确保熔断生效,再查 journalctl -u yourapp.service -n 50 里的首条失败记录,才可能定位到真实原因。











