Node.js 在 Linux 上的缓存策略配置指南
一 核心思路与分层策略
- 在 HTTP 层通过响应头控制浏览器与中间层(如 CDN/代理)的缓存行为,优先使用强缓存,必要时配合协商缓存,敏感内容直接禁用缓存。
- 在 应用层用内存缓存(如 LRU、简单对象)降低数据库/后端压力,多实例或跨进程使用 Redis/Memcached 共享缓存。
- 在 反向代理层(如 Nginx/Apache)配置代理缓存与路径匹配,统一对外缓存策略。
- 在 操作系统层合理利用 Linux 文件系统页缓存,并按需调整内核参数以平衡吞吐与延迟。
二 HTTP 层配置
- 强缓存与协商缓存要点
- 强缓存:使用 Cache-Control: public, max-age=…;对共享缓存(如 CDN)可用 s-maxage;对长期不变的带哈希静态资源可设置较长缓存(如 1 年)。
- 协商缓存:使用 ETag/If-None-Match 或 Last-Modified/If-Modified-Since,未变更返回 304 Not Modified,节省带宽。
- 禁用缓存:对登录、支付、实时数据等敏感内容使用 Cache-Control: no-store;如需每次验证可用 no-cache(注意:no-cache 并非“不缓存”,而是“用前必须验证”)。
- 在 Node.js/Express 中的实践
- 静态资源长缓存(带内容哈希的文件名):
- 示例:对 JS/CSS/图片/字体设置 max-age=31536000(1 年);HTML入口使用 no-cache + ETag 保证及时更新。
- API 数据短缓存或协商缓存:
- 示例:对频繁变动的数据设置 max-age=60 或 no-cache + ETag,命中验证返回 304。
- 原生 Node.js 设置示例:
- 示例:使用 response.writeHead(200, { ‘Cache-Control’: ‘public, max-age=3600’ }) 设置强缓存。
- 安全与兼容性补充
- 对敏感内容可同时设置 Pragma: no-cache 与 Expires: 0 以兼容旧客户端与 HTTP/1.0 代理。
三 应用层缓存
- 内存缓存(单实例)
- 使用 LRU 或简单对象做热点数据缓存,设置 TTL 与淘汰策略,避免内存泄漏。
- 示例:使用 lru-cache 创建实例,设定 max 与 maxAge,在读写路径上命中则返回,未命中则回源并写入缓存。
- 分布式缓存(多实例/跨进程)
- 使用 Redis/Memcached 共享缓存,典型模式为 get → 命中返回 → 未命中回源 → setex 设置过期时间。
- 示例:Redis 客户端 get/setex 配合 JSON.stringify/parse 存取结构化数据。
四 反向代理与 CDN 层
- Nginx 作为反向代理与缓存
- 示例:配置 proxy_cache_path、proxy_cache、按状态码设置 proxy_cache_valid,对静态与 API 路径分别制定策略,统一对外缓存时效与容量。
- CDN 加速静态资源
- 将带哈希的 JS/CSS/图片/字体 交由 CDN 长期缓存,入口 HTML 与版本敏感资源通过 no-cache/短 TTL 或 CDN 刷新机制控制更新。
五 操作系统层优化
- 利用 Linux 文件系统页缓存
- Node.js 读写文件时,内核会自动将热点数据缓存在内存中,通常无需额外代码即可受益。
- 内核参数调优(按需)
- 调整 vm.dirty_ratio 与 vm.dirty_background_ratio 可影响脏页回写与 I/O 行为,示例值:vm.dirty_ratio=40、vm.dirty_background_ratio=10;修改 /etc/sysctl.conf 后执行 sysctl -p 生效。
- 建议:仅在明确瓶颈且了解影响时调整,避免引发抖动或数据丢失风险。