960MB 内存的机器上,我都跑些什么
这台机器是年付的小 VPS,1 核 960MB。它的定位很明确:跑几个轻量服务和反向代理,不做任何编译、不跑数据库。即便这样,内存也经常在 80% 上下晃,逼着我把每个进程都过了一遍。
先看清“已用内存”到底是什么
free -m 里的 used 并不是进程真正占用的内存,page cache 和可回收的 slab 也会计入。判断是否真的吃紧,看 available 更准。我的机器上 used 常年 600MB+,但 available 还有 650MB 左右,说明大部分是缓存。
$ free -m
total used free shared buff/cache available
Mem: 961 164 121 0 674 655
真正需要关注的是 available 掉到 100MB 以下、同时 si/so 出现非零值的时候。那才是要出事的信号。
swap:留一点,但别指望它
我给这台机器留了 1GB swap,vm.swappiness=10。目的不是“扛住内存压力”,而是让内核在回收匿名页时有一点缓冲,避免 OOM killer 直接动手。实际运行中 vmstat 1 的 si/so 长期是 0,说明 swap 只是保险。
systemd 单元里的资源约束
比调内核参数更有效的是给每个服务设上限。我常用的几行:
[Service]
MemoryMax=200M
MemoryHigh=160M
TasksMax=256
LimitNOFILE=65535
Restart=always
RestartSec=2s
MemoryHigh 是软限制,超过之后内核会优先回收这个 cgroup 的页;MemoryMax 是硬限制,超过直接 OOM 该单元。把两者拉开一点,能让服务自己感知到压力,而不是被整机 OOM 波及。
日志是隐形的大户
journald 默认会把日志写到 /var/log/journal,长期运行后几个 GB 很常见。我的配置是:
[Journal]
SystemMaxUse=200M
SystemMaxFileSize=20M
MaxRetentionSec=2week
nginx 的 access log 也做了按天轮转、保留 14 天。这两个动作加起来,磁盘占用从 11GB 降到了 6GB 左右。
不装什么,比装什么更重要
这台机器上没有 Docker,没有数据库,也没有编译工具链。所有需要编译的东西都在本地或 CI 里做好,只把二进制传上去。这不是洁癖,是资源约束下的必然选择:一个 dockerd 加上容器运行时,空闲状态就要吃掉 100MB 以上。
另外,定时任务尽量合并。原本有 5 个 cron 在凌晨跑,现在合成一个脚本串行执行,避免同一时刻多个进程抢占 CPU 导致负载尖刺。
一条经验
小机器的稳定性,八成来自“少跑东西”,两成来自“跑的东西有边界”。调参能解决的问题,通常不如删掉一个不需要的服务来得彻底。