◈ 夜宵吧

重启那 52 秒:内核、swap 和一个不生效的服务

apt upgrade 跑完,uname -r 还是旧的。

这种事不报错、不告警:/boot 里躺着新内核,系统跑的却是旧的。

启动阶段:GRUB 选内核,内核解压与初始化,systemd 拉起站点服务,最后首字节返回;前三个阶段吃掉全部 52 秒
52 秒里,应用自己启动不到 1 秒。慢的全在前面。

内核不会提醒你

有人以为 /var/run/reboot-required 会出现——那其实是 needrestart 这类工具写的,内核包本身不写。

所以得自己比对:

const running = os.release();              // 6.12.88+deb13-amd64
const installed = readdirSync('/boot')
  .filter(f => f.startsWith('vmlinuz-'))
  .map(f => f.slice(8));                   // 每个内核一条 vmlinuz-*
const pending = installed.filter(v => v !== running);

有差异就在首页亮一条提示,剩下的交给时间。

重启前先确认值不值得

1 GB 的机器重启一次,所有服务都要重新起来。先列清楚要验证什么:

  • 数据完整性(PRAGMA integrity_check)
  • 备份是不是最新一份
  • 哪些服务会自启、哪些不会

第三步最容易出问题:某个服务是手动起的,systemctl enable 忘了做,重启后就没了。

把 10 个单元逐个查一遍 is-enabled,全是 enabled 才敢动。

那 52 秒

systemctl reboot 到站点能访问,52 秒。

不是硬件需要的 20 秒——要起 8 个服务,其中代理要做一次 UDP 缓冲预分配,内网穿透要重建隧道,防护组件要加载规则。

顺序不完全可控。所以重启后要逐项验证,而不是「能打开网页就算好了」:

  • 内核版本对不对
  • 服务列表里有没有非 active
  • 站点路由是不是全 200
  • 代理和隧道的防火墙规则有没有回来(它们由一个 15 秒周期的定时器跟随端口,要等一轮)
  • 数据完好、监控在采样

这一圈查完才算重启成功。

swap 那个默认值

vm.swappiness 默认 60。

意思是:内存用到 40% 左右,内核就开始积极地把匿名页换出去。

而匿名页装的是进程堆、栈、缓冲区——这些是「换出去快、换回来慢」的热数据。换出去之后每次访问都要读盘,延迟从纳秒级变成毫秒级。

对小内存机器,这个默认值偏激进。

改到 10。但不是 0:完全不换出,内核会在临界点直接动手杀进程,一点缓冲都没有。留一点,换换反应时间。

配置放进 /etc/sysctl.d/,重启后自动重放,不需要额外的服务。

为什么没做 swapoff

常见流程是:改完 swappiness,swapoff -a && swapon -a 让新参数立刻作用于已有数据。

但这一步的前提是 swap 里已经有页面需要搬回内存。

实测 swap 有效占用是 0(swapon --show 里那 268 KB 是元数据)。这种情况下执行 swapoff,只会凭空制造一次内存抖动,没有任何收益。

先查再动,比照着流程走重要。

那个「泄漏」

重启后监控显示:某个常驻进程内存峰值 270 MB,三分钟后回落到 84 MB。

第一反应是泄漏。

但泄漏的曲线是单调上升,不会回落。真相是按需分配的缓冲:启动时预分配一大块(收发队列、连接池),空闲时归还。

判断是不是泄漏,看的是「回不回落」,不是「峰值多高」。

一个失败但不影响功能的服务

networking.service 是 failed。

日志:Failed to get interface index: No such device。

原因是 Debian 13 上 ifupdown 和 systemd-networkd 并存,某个接口名匹配不上。

但网卡收发正常、路由正常、所有服务都通——这个失败是形式上的。

留着的理由很简单:它没有害处,而「修好」它需要动网络配置,那才是真有风险的动作。

不修的判断也要写下来。否则下次看到它,还会紧张一次。

八天后,swap 里又进去了 198 MB

改完 swappiness=10,我以为不会再大量换出了。八天后:

Swap: 544 total, 198 used, 346 free
Mem:  1031 total, 636 available

还在换。

不是 swappiness 没生效——它确实改的是「多积极地把冷页换出去」,而现在换出去的正是冷页。问题是这台机器的内存本来就不够:1031 MB 里装着一个 Web 服务、一个量化面板、一个代理、一套防护,剩 636 MB 可用;而一个后台开着的浏览器就要 537 MB。

swappiness 改的是倾向,不改容量。

所以那一节的结论要收窄一点:调低 swappiness 是对的(它让匿名页尽量待着、优先换出文件缓存),但它不是解药。真正的解法是减进程或加内存,那是另一件事。

一条判断可以用:如果 swap 用了、但 available 还高,说明换出去的是真正的冷页,正常;如果 swap 用了、available 也低,说明是容量不够,调参没用。