Lab / Systems

VPS 内存压力冻结排查与 earlyoom 预防

记录一次腾讯云 VPS 无响应后的排查过程:日志断点、内存压力判断、earlyoom 配置,以及 Lucky/Twikoo Docker 内存限制。

背景

2026-06-15 早上,腾讯云 VPS 出现无法连接的问题。腾讯云控制台里的状态监控信息也没有正常获取到。随后通过控制台重启 VPS,系统恢复。

这次记录用于保留排查依据和后续预防措施,避免下次只记得“重启好了”,但忘记真正的风险点。

现象

  • SSH 无法连接。
  • 腾讯云控制台监控信息获取不到。
  • 控制台重启后恢复。
  • 重启后博客、Twikoo、Docker、SSH 均可正常运行。

排查结论

更像是 内存压力导致系统冻结或严重卡死,而不是单个服务挂了。

关键日志:

Jun 15 10:00:36 systemd-journald[295]: Under memory pressure, flushing caches.
Jun 15 10:00:59 systemd-journald[295]: Under memory pressure, flushing caches.

日志时间线:

上一个 boot 最后日志:2026-06-15 10:00:59
本次重启后新 boot:2026-06-15 10:24:21

中间没有正常 shutdown 记录,说明不是优雅关机,更像系统在 10:01 左右失去响应,然后在 10:24 被手动重启。

未发现的问题

这次排查没有看到以下典型故障证据:

  • 没有明确 kernel panic 记录。
  • 没有明确 Out of memory / Killed process 记录。
  • 没有磁盘空间满。
  • 没有 inode 满。
  • 没有 Docker、Lucky、Twikoo 崩溃记录。
  • 没有 GitHub Actions、rsync、Astro build、ffmpeg 在故障时间附近运行。
  • 没有异常 SSH 成功登录,仅有公网扫描类连接被拒。

当前资源状态

重启后检查:

内存:1.9 GiB
Swap:2.0 GiB
磁盘:49G,已用约 13G
systemd failed units:0

重启后主要服务内存大致为:

Lucky:约 180-210 MiB
Twikoo:约 50-125 MiB
Tailscale:约 100 MiB
Docker daemon:约 90 MiB
腾讯云 YunJing / barad / stargate agent:持续运行,占用一部分内存

这台机器只有 2G 内存,日常服务本身不重,但余量并不大。如果某个进程瞬时膨胀,可能在 OOM killer 留下完整记录前就把系统拖到不可响应。

已执行的预防措施

安装并启用 earlyoom

安装:

apt-get update
apt-get install -y earlyoom

配置文件:

/etc/default/earlyoom

当前参数:

EARLYOOM_ARGS="-r 60 -m 10 -s 10 --avoid '(^|/)(systemd|sshd|ssh|dockerd|containerd|earlyoom)$'"

含义:

  • -r 60:每 60 秒记录一次状态。
  • -m 10:可用内存低于 10% 时触发第一阶段处理。
  • -s 10:可用 swap 低于 10% 时触发第一阶段处理。
  • --avoid:尽量避免杀掉基础系统和远程连接相关进程。

服务状态:

systemctl status earlyoom --no-pager

确认结果:

earlyoom.service active (running)

限制 Lucky 容器内存

配置文件:

/opt/lucky/compose.yml

增加:

mem_limit: 512m
memswap_limit: 768m

限制 Twikoo 容器内存

配置文件:

/opt/twikoo/compose.yml

增加:

mem_limit: 384m
memswap_limit: 512m

重建容器

cd /opt/lucky
docker compose up -d

cd /opt/twikoo
docker compose up -d

验证:

docker inspect lucky twikoo --format '{{.Name}} Memory={{.HostConfig.Memory}} MemorySwap={{.HostConfig.MemorySwap}}'
docker stats --no-stream

确认结果:

/lucky  Memory=536870912  MemorySwap=805306368
/twikoo Memory=402653184  MemorySwap=536870912

实时占用示例:

lucky   181.4MiB / 512MiB
twikoo   51.39MiB / 384MiB

服务验证

重建容器和启用 earlyoom 后验证:

systemd failed units:0
lucky:Up
twikoo:Up
博客 HTTPS:HTTP/2 200
评论服务:HTTP/2 200

Twikoo 日志显示:

Twikoo database stored at /app/data
Twikoo is using loki database
Twikoo function started on host :: port 8080
Connected to database

配置备份

修改前已备份:

/etc/default/earlyoom.bak.20260615103959
/opt/lucky/compose.yml.bak.20260615104014
/opt/twikoo/compose.yml.bak.20260615104014

后续观察

如果之后仍然发生整机无响应:

  1. 优先查看上一个 boot 日志:

    journalctl --list-boots --no-pager
    journalctl -b -1 -p warning..alert --no-pager
    journalctl -b -1 -k --no-pager
  2. 查看 earlyoom 是否有杀进程记录:

    journalctl -u earlyoom --no-pager
  3. 查看容器是否触发 OOM:

    docker inspect lucky twikoo --format '{{.Name}} OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}}'
  4. 如果频繁发生,考虑升级 VPS 到 4G 内存,或减少腾讯云安全/监控 agent、Tailscale、Codex 会话等常驻组件。

判断

这次事故更接近:

低内存小机 + 瞬时内存压力 + 系统未及时杀进程 = 整机冻结

当前防护目标不是让机器永远不会出问题,而是在异常内存压力出现时,让系统优先牺牲异常进程,而不是整台 VPS 失联。