静态资源服务器大并发下载易因Page Cache占满内存触发OOM;应通过MemAvailable、Cached与SReclaimable差值确认问题,调低vm.vfs_cache_pressure、启用aio threads/directio、降低swappiness、禁用zswap,并用CDN或X-Accel-Redirect规避内核缓存。

静态资源服务器在大并发下载时,内核会把大量文件数据缓存进 Page Cache,本意是加速后续读取,但若物理内存有限、请求又高度重复或单次传输体积大(如视频、镜像包),Page Cache 就可能吃光可用内存,触发 Swap 持续写入,最终 swap 耗尽、OOM Killer 启动,服务直接崩溃。
确认是否真由 Page Cache 主导内存压力
别只看 free -h 的 “used” 值——它包含大量可回收的 cache。重点看:
- available:低于 5% 物理内存时,系统已实际缺内存
- buff/cache 占比是否远超应用实际 RSS(如 nginx worker 进程总 RSS 仅 2GB,但 buff/cache 达 14GB)
- 执行 cat /proc/meminfo | grep -E "Cached|SReclaimable|MemAvailable",对比 Cached + SReclaimable 与 MemAvailable 差值
限制 Page Cache 对静态文件的影响
对纯静态资源服务(如 Nginx 托管 ISO、ZIP、MP4),可大幅降低内核缓存意愿,避免“为缓存而缓存”:
- 设置 vm.vfs_cache_pressure = 200(默认 100):加快 inode/dentry 缓存回收,间接缓解内存挤占
- 关键一步:启用 sendfile + tcp_nopush,并关闭 epoll ET 模式下的 read() 预读(Nginx 默认已优化,但需确认未被覆盖)
- 在 Nginx location 块中添加:
aio threads; # 使用线程池异步读,绕过内核 page cache(适用于 ext4/xfs)
directio 8m; # 文件大于 8MB 时跳过 page cache,直接 DMA 到 socket buffer
控制 Swap 行为,防止雪崩式交换
Swap 不是故障,但无节制使用会拖垮 I/O 并引发连锁反应:
- 将 vm.swappiness 从默认 60 降至 1–10:仅在物理内存真正告急时才换出,避免 cache 被轻易踢进 swap
- 确保 swap 分区/文件大小 ≥ 物理内存 × 0.5(如 32GB RAM → 至少 16GB swap),但不盲目设过大(>2×RAM 易掩盖真实泄漏)
- 禁用 zram 或 zswap:压缩虽省空间,但高并发下载下 CPU 压力剧增,反而加剧延迟和调度抖动
架构层规避:让 Page Cache “不碰核心路径”
最彻底的方式,是让大文件根本不走内核文件缓存路径:
- 用 nginx + X-Accel-Redirect 或 Apache mod_xsendfile,后端应用只校验权限,由 Web 服务器调用 sendfile() 直传磁盘文件
- 部署 CDN 或对象存储(如 MinIO + S3 API),让静态资源卸载到边缘或专用存储节点,原服务器只做元数据和跳转
- 对超大文件(>1GB),改用 range request + streaming response,配合 response buffering off,避免整个文件加载进内存或 cache


















