© 2025 Rocky. All rights reserved.

|浙ICP备2025179428号-3|

魔法施展中...

技术文章

技术实践

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

2025-11-02
5 分钟
...
Java健康检查故障排查Ubuntusupervisor

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

具体操作

  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

💡 关于技术判断: 本文反映了我在真实系统中评估技术风险的思考方式。 我现在专注于为创始人和决策者提供独立的后端与架构风险评估服务。 如果您在重大技术决策前需要第三方意见,了解评估服务或联系咨询。

感谢阅读!如果您觉得这篇文章有帮助,欢迎分享给更多的朋友。

上一篇
技术实践

SSLcat:重新思考 Web 服务器的设计边界

SSLcat 试图在 Web 服务器的边界上做一些不同的事情。它不只是代理请求,而是把证书管理、应用部署、容器编排这些原本分散的事情整合在一起,重新定义了 Web 服务器的职责范围。

下一篇
生活随笔

沮河记忆之四

很多年没有再沿着沮河走去外婆家的那条旧路了,虽然我有几次还在心里默默把那条路盘了又盘,生怕哪天就在记忆里彻底弄丢它。

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

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

加载中...

猜你喜欢

产品思考

聊聊我的薪资外收入(non-salary income)

我其实所谓工资外收入不太在乎,作为程序员,薪资相对于传统行业来说相对还是薪资较高的,多花精力在工作上,获得的回报远高于去做兼职什么的。不过既然今天被点名到这个话题,我就如实回答一下关于薪资外收入和被动收入。

2022-06-01
生活随笔

关于独立

- 第二层是经济独立,会自己赚钱养活自己。

2022-01-16
技术实践

Apache Drill 架构总览

Apache drill是在大规模数据集场景下,可以低延迟地进行结构和半结构化/嵌套数据结构查询的一个分布式查询引擎。受到谷歌公司的Dremel的启发,Drill被设计出来以支持几千个节点和PB级别的数据规模下,支持交互响应级别的商务智能分析和查询。 Drill也适用到在大规模数据集场景下进行...

2017-04-04