魔法施展中...

一个诡异的 java 应用健康检测失败排查

5 分钟
...

一个诡异的 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.servicesupervisor.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,避开业务高峰期。

具体操作

  1. 先创建覆盖配置目录:
mkdir -p /etc/systemd/system/apt-daily-upgrade.timer.d
  1. 创建覆盖配置文件,把时间改到凌晨2点:
cat > /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf << EOF
[Timer]
OnCalendar=*-*-* 2:00
RandomizedDelaySec=60m
EOF
  1. 重新加载配置并重启定时器:
systemctl daemon-reload
systemctl restart apt-daily-upgrade.timer
  1. 验证一下配置是否生效:
systemctl status apt-daily-upgrade.timer
systemctl list-timers apt-daily-upgrade.timer

看到下次执行时间变成凌晨2点就对了。

方案二:禁用 fwupd 服务(可选)

如果服务器不需要固件更新功能(大多数情况下确实不需要),可以禁用 fwupd 服务,避免它在更新过程中影响其他服务。

具体操作

  1. 停止并禁用 fwupd 相关服务:
systemctl stop fwupd.service
systemctl stop fwupd-refresh.service
systemctl disable fwupd.service
systemctl disable fwupd-refresh.service
  1. 如果确定不需要,也可以直接卸载:
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

后续建议

  1. 监控应用重启频率:定期检查一下应用的 uptime,如果发现频繁重启,及时排查原因。

  2. 优化健康检查:可以考虑给健康检查加个容错机制,比如允许短暂的服务中断,避免误报。

  3. 定期检查系统更新:虽然自动更新很方便,但还是建议定期看看更新日志,了解系统都更新了啥。

相关文件

  • 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

📮 订阅更新
每周收到最新文章推送,不错过精彩内容

💡 我们尊重您的隐私,不会将邮箱用于其他用途

加载中...