Nginx缓存未命中默认异步透传,无需开启异步,关键在于避免auth_request、if/正则rewrite、proxy_buffering off无超时、directio小文件等隐式同步操作,并通过连接复用、内存缓冲、文件缓存及cache_lock+stale机制优化性能。

Nginx 在缓存未命中时默认就是异步透传、不阻塞当前请求的——它根本不会“等结果”,而是立即发起上游请求,同时继续处理其他事件。所谓“直接异步生成”,本质是让未命中路径全程非阻塞、零等待、可并发,关键不在“开启异步”,而在避免配置引入隐式同步行为。
缓存未命中本身已是异步,重点是别把它变同步
Nginx Worker 处理 cache miss 的天然流程就是异步的:查 keys_zone → 无命中 → 立即复用连接池发 upstream 请求 → 注册 epoll 事件等待响应 → 自己去轮询别的连接。你不需要额外“开启异步”,反而要小心关掉那些会把它拖成同步的操作:
-
禁用
auth_request:该指令强制同步等待子请求完成,一旦启用,整个请求链(包括未命中的回源)都会卡住。 -
避免在 location 中使用
if或复杂正则 rewrite:这些会在事件循环中引入同步判断和系统调用,增加延迟。 -
不要开启
proxy_buffering off却不配超时:虽然流式透传需要关闭缓冲,但若没设proxy_read_timeout,后端挂起会导致连接长期滞留,间接阻塞 worker 资源。 -
慎用
directio处理小文件:对未命中的静态资源,directio会让 read() 进入 D 状态(内核级阻塞),直接卡死 worker;仅对 ≥4MB 大文件 +aio on才安全。
让未命中流量真正轻量、快速、可扩展
未命中虽不阻塞,但响应速度仍受后端和本地 I/O 影响。以下配置能进一步压低延迟、提升吞吐:
-
复用 upstream 连接:
upstream backend { server 10.0.1.10:8080; keepalive 32; # 复用连接,减少握手开销 } -
跳过临时文件写入(防小响应落盘卡顿):
proxy_max_temp_file_size 0; # 强制全内存缓冲或直通 proxy_buffer_size 16k; proxy_buffers 16 64k; proxy_busy_buffers_size 256k;
-
加速文件系统访问(对静态未命中):
open_file_cache max=10000 inactive=60s; open_file_cache_valid 60s; open_file_cache_min_uses 2;
防止未命中引发雪崩,用锁+后台更新兜底
单次未命中异步没问题,但大量并发请求打同一未命中 key,就会触发大量重复回源。这不是阻塞问题,而是上游压力问题。解决方式不是让请求排队,而是收敛回源、释放用户侧等待:
-
启用缓存锁,只放行首个请求:
proxy_cache_lock on; proxy_cache_lock_timeout 5s; # 超时后允许 fallback 到 stale
-
配合
proxy_cache_use_stale updating,让后续请求秒回旧内容:proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; # 后台静默刷新,不影响用户
这样,第一个请求去回源(异步),其余请求立刻拿到旧缓存(或 5xx/timeout 时的 stale 内容),整个过程对客户端完全无感,worker 也始终在线处理新连接。
不复杂但容易忽略。


















