Spring Boot 服务挂了却没重启?先分清 systemd 的三次判断

线上有个 Spring Boot 服务退出后没有再起来,第一反应通常是补一句 Restart=always。我见过这么改的,结果是发版时正常停掉的进程也被拉回来了,现场更乱。

systemd 不是看到进程没了就无脑重启。它至少要过三道判断:这次退出算不算失败,重启次数有没有撞限额,当前追踪到的到底是不是你以为的那个主进程。

先看退出为什么没有被算成失败

对常驻服务,Restart=on-failure 通常是比 always 更稳的默认选择。systemd 的官方说明也把它列为长运行服务的推荐项。

但它只会在这些情况重启:

  • 进程返回非零退出码
  • 进程异常被信号终止
  • 服务启动或运行超时

退出码是 0,或者是有意停止的 SIGTERM、SIGINT,都不属于它要补救的故障。

所以排查时别只盯着「进程没了」。有些启动脚本把 Java 异常吃掉以后又 exit 0,systemd 会认为这次服务正常结束。手动执行 systemctl stop 后不自动拉起也完全正常。

先看这一组信息:

bash 复制代码
systemctl status demo-api
systemctl show demo-api -p Result -p ExecMainCode -p ExecMainStatus -p NRestarts
journalctl -u demo-api -b --no-pager -n 100

我一般先找两件事:最后一次退出的 code 和 status 是什么,日志里失败发生在 Java 进程里还是发生在启动命令本身。

重启策略生效了,也可能被限频拦住

服务连续崩溃时,systemd 会遵守 RestartSec= 的等待时间,但不会无限次地拉起。它还会按 StartLimitIntervalSec= 和 StartLimitBurst= 做启动限频。

看到 start-limit-hit,不要急着把阈值调大。那只是在让错误更快刷屏。先把导致崩溃的配置、依赖或端口问题修掉,之后再清理失败状态:

bash 复制代码
sudo systemctl reset-failed demo-api
sudo systemctl restart demo-api

下面这份 unit 文件适合先把行为讲清,不是照抄到所有机器上的万能模板:

ini 复制代码
[Unit]
Description=demo-api
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
User=app
WorkingDirectory=/srv/demo-api
Type=exec
ExecStart=/usr/bin/java -jar /srv/demo-api/app.jar
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

这里的 60 秒和 3 次只是一个明确的保护边界。实际值要看服务启动成本、依赖恢复速度和报警承受能力。把 RestartSec=0 当成「恢复更快」往往不是好事,它会让崩溃循环更快撞上限频。

Type=exec 解决的不是应用启动失败

很多 unit 文件完全不写 Type=,默认是 simple。对于长期运行的 Java 进程,Type=exec 有个很实在的好处:可执行文件不存在、用户不存在这类 execve 之前的启动错误,systemd 能更可靠地记录为启动失败。

但别把它神化。JAR 已经被 Java 拉起来,应用随后因为数据库连不上而退出,这仍然要靠退出状态和日志来判断。它不会替 Spring Boot 判断「业务已就绪」。

面试里怎么收这题

被问「为什么不用 Restart=always」,我会先说清目标:守住异常退出,不干预运维的正常停止。

然后补一句,真正可靠的配置不只是一个 Restart。要同时确认退出状态能反映失败,给重启留出间隔,再让限频把持续崩溃挡住。这样面试官继续问服务为什么没拉起,才有具体的排查顺序,不会只剩一句「加个重启策略」。

资料核对:systemd.service(5)、systemd.unit(5)、Spring Boot Reference Documentation 的 Linux systemd service 示例。

相关推荐
顽疲1 小时前
java springboot vue 养老系统源码详解:请假 care_leave 销假与床位停费日扣实践
java·vue.js·spring boot
Java_AI工程师2 小时前
Spring4 / SpringBoot1.x 老项目想接入 AI?不用升级框架!3 套无痛落地方案
java·人工智能·spring boot
VimorphTech2 小时前
Java 文件缓存实战:如何避免读到未下载完成的视频?
java·spring boot
十年Java程序媛4 小时前
JVM 内存区域与对象内存布局|new 对象底层流程,对象头 MarkWord 详解
java·jvm·spring boot
linyb极客之路4 小时前
Spring Boot 2升3太痛苦?用OpenRewrite批量搞定,少走90%弯路!
spring boot
171320330计算机毕设编程4 小时前
计算机毕业设计 基于springboot+vue的在线观鸟视频播放网站 LW PPT
java·大数据·vue.js·spring boot·算法·课程设计
星辰云-9 小时前
# 基于Spring Boot的德州特产扒鸡商城系统(毕设|源码|论文|演示视频)
spring boot·后端·课程设计
星辰云-10 小时前
基于Spring Boot的旅游景点票务系统的设计与实现(毕设项目,附完整源码)
spring boot·后端·课程设计
十年Java程序媛11 小时前
JVM 基础与 GC 垃圾回收详解|可达性分析、分代模型、垃圾收集器、STW
java·开发语言·jvm·spring boot·后端·面试
她的男孩11 小时前
JAR 全对仍 checksum mismatch:Forge Admin 把 Flyway 从 filesystem 改成 classpath
java·数据库·spring boot