一个诡异的 java 应用健康检测失败排查
现象
早上6点41分左右,飞书突然收到健康检查失败的通知,说 van-course 应用的 /health 接口访问不了。我搜了一下飞书机器人日志,这几天持续有,两台线上服务器都有,发生时间还不一样,daily 环境就没有。于是赶紧上服务器看看怎么回事。
排查过程
先看看应用状态
第一反应是检查应用是不是挂了:
supervisorctl status van-course
应用显示是 RUNNING,但 uptime 只有5小时,明显是重启过了。什么时候重启的呢?
查 supervisor 日志
看看 supervisor 的日志,定位一下重启时间:
journalctl -u supervisor --since '2025-11-02 06:30:00' --until '2025-11-02 07:00:00'
找到了两个关键时间点:
-
06:38:21 - supervisor 被停止
-
06:38:22 - supervisor 重新启动
-
06:40:47 - supervisor 再次被停止
-
06:40:49 - supervisor 再次启动
van-course 应用也在这两个时间点被重启了。看起来是 supervisor 重启导致的。
看看系统日志
supervisor 为啥会重启呢?查一下系统日志,看看那个时间点发生了什么:
journalctl --since '2025-11-02 06:30:00' --until '2025-11-02 07:00:00' | grep apt-daily
发现了!同一个时间点 apt-daily-upgrade.service 正在执行:
-
06:38:13 - apt-daily-upgrade 开始执行
-
06:38:21 - 同时停止了
fwupd.service和supervisor.service -
06:41:04 - apt-daily-upgrade 执行完成
原来是系统自动更新搞的鬼。
确认定时任务配置
看看这个自动更新是怎么配置的:
cat /lib/systemd/system/apt-daily-upgrade.timer
配置是这样的:
[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
意思是每天早上6点开始,随机延迟0-60分钟执行。所以实际执行时间是 6:00-7:00 之间,正好和我们问题发生的时间对上了。
测试环境因为是用的 aliyun镜像, 基于centos 的衍生版,所以没有这套体系,就没有发生这个问题。
根本原因
问题出在系统级的 apt-daily-upgrade 定时任务上。Ubuntu 默认会在每天早上6:00-7:00之间执行自动安全更新。
更新过程中,系统会停止一些服务(比如 fwupd 固件更新服务),连带着 supervisor 也被停了。我们的 van-course 应用是由 supervisor 管理的,supervisor 一重启,应用也跟着重启了。
重启那会儿,应用有短暂的服务中断,健康检查就失败了。
解决方案
方案一:调整 apt-daily-upgrade 执行时间(推荐)
最简单的办法是把自动更新的时间改到凌晨2:00-3:00,避开业务高峰期。
具体操作
- 先创建覆盖配置目录:
mkdir -p /etc/systemd/system/apt-daily-upgrade.timer.d
- 创建覆盖配置文件,把时间改到凌晨2点:
cat > /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf << EOF
[Timer]
OnCalendar=*-*-* 2:00
RandomizedDelaySec=60m
EOF
- 重新加载配置并重启定时器:
systemctl daemon-reload
systemctl restart apt-daily-upgrade.timer
- 验证一下配置是否生效:
systemctl status apt-daily-upgrade.timer
systemctl list-timers apt-daily-upgrade.timer
看到下次执行时间变成凌晨2点就对了。
方案二:禁用 fwupd 服务(可选)
如果服务器不需要固件更新功能(大多数情况下确实不需要),可以禁用 fwupd 服务,避免它在更新过程中影响其他服务。
具体操作
- 停止并禁用 fwupd 相关服务:
systemctl stop fwupd.service
systemctl stop fwupd-refresh.service
systemctl disable fwupd.service
systemctl disable fwupd-refresh.service
- 如果确定不需要,也可以直接卸载:
apt remove fwupd fwupd-signed
方案三:配置 supervisor 服务保护(备选)
如果不想调整更新时间,可以尝试配置 supervisor 服务,让它不被 apt-daily-upgrade 停止。但这需要修改 systemd 的依赖关系,比较复杂,不太推荐。
验证
配置完成后,可以用这些命令验证一下:
# 查看下次执行时间,应该显示凌晨2点
systemctl list-timers apt-daily-upgrade.timer
# 看看 supervisor 和应用的状态是否正常
supervisorctl status
# 看看应用日志,确认没有异常重启
tail -f /home/admin/van-course/logs/supervisor-van-course-stdout.log
后续建议
-
监控应用重启频率:定期检查一下应用的 uptime,如果发现频繁重启,及时排查原因。
-
优化健康检查:可以考虑给健康检查加个容错机制,比如允许短暂的服务中断,避免误报。
-
定期检查系统更新:虽然自动更新很方便,但还是建议定期看看更新日志,了解系统都更新了啥。
相关文件
-
apt-daily-upgrade 定时器配置:
/lib/systemd/system/apt-daily-upgrade.timer -
覆盖配置目录:
/etc/systemd/system/apt-daily-upgrade.timer.d/ -
supervisor 日志:
journalctl -u supervisor -
应用日志:
/home/admin/van-course/logs/supervisor-van-course-stdout.log