排查 nginx 代理临时文件占用磁盘过高的问题,核心在于定位并清理由 `proxy_temp` 目录产生的未合并文件。这些文件通常是因为大文件上传或下载中断、nginx 进程重启导致正在进行的传输被截断而形成的。解决步骤包括:首先检查 `/var/lib/nginx/tmp/proxy`(具体路径取决于配置)的磁盘占用情况;其次,确认是否有异常的大文件或大量碎片文件;最后,在确保没有活跃连接的情况下,安全地删除这些临时文件以释放空间。

Nginx 代理临时文件的生成机制是什么
Nginx 在处理反向代理请求时,如果响应体较大,会先将数据写入磁盘上的临时目录,而不是全部加载到内存中。这个目录由 `proxy_temp_path` 指令定义,默认通常是 `/var/lib/nginx/tmp/proxy` 或 `/var/cache/nginx/proxy_temp`。当客户端断开连接、Nginx 重启或发生错误时,这些正在写入的临时文件不会被自动清理,从而堆积占用磁盘空间。

server {
listen 80;
server_name example.com;
# 设置代理临时文件存储路径
proxy_temp_path /var/lib/nginx/tmp/proxy;
location /api/ {
proxy_pass http://backend_server;
# 关键配置:允许接收较大的请求体
client_max_body_size 50m;
# 关键配置:设置代理缓冲行为
# off: 禁用缓冲,直接流式传输,不产生临时文件
# auto: 根据响应头决定,可能产生临时文件
proxy_buffering on;
# 设置单个缓冲大小,影响何时开始写磁盘
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}
上述配置展示了如何控制代理缓冲。当 proxy_buffering 开启且响应头中的内容长度超过缓冲区总和时,Nginx 会将超出部分写入 proxy_temp_path 指定的目录。如果此时连接中断,这些写入的文件就会残留。通过调整 proxy_buffer_size 和 proxy_buffers,可以控制触发磁盘写入的阈值。对于实时性要求高且带宽充足的场景,可以考虑关闭缓冲以避免临时文件产生。
如何安全地清理这些临时文件而不影响服务
直接删除 rm -rf 临时文件目录下的内容是危险的,因为可能有活跃的写入进程持有文件句柄,导致删除后空间不释放或引发错误。正确的做法是识别并终止相关的 Nginx worker 进程,或者使用更安全的移动/重命名策略。在生产环境中,最稳妥的方式是重启 Nginx 服务,这会优雅地关闭所有 worker 进程并清理其持有的临时文件描述符,随后临时文件会被操作系统回收。
# 1. 查看临时目录占用情况 ls -lhS /var/lib/nginx/tmp/proxy | head -n 10 # 2. 查找正在使用该目录的进程(可选,用于调试) lsof +D /var/lib/nginx/tmp/proxy # 3. 安全重启 Nginx (推荐) nginx -s reload # 或者完全重启以彻底清理 systemctl restart nginx # 4. 如果无法重启,可尝试手动清理(需确保无活跃写入) # 注意:这可能导致正在进行的代理请求失败 find /var/lib/nginx/tmp/proxy -type f -mtime +1 -delete
执行 nginx -s reload 会启动新的 worker 进程并逐步关闭旧的,旧进程持有的临时文件会在其退出时被清理。如果磁盘空间极度紧张,无法等待重载完成,可以使用 find ... -delete 命令删除较旧的临时文件,但这会中断当前正在通过这些文件传输的请求。建议在低峰期操作,并监控 dmesg 或 Nginx error log 以确认没有因文件丢失导致的报错。
如何通过配置减少临时文件的产生频率
除了事后清理,优化 Nginx 配置可以从源头减少临时文件的生成。主要策略包括:增大内存缓冲区以容纳更多响应数据,避免过早写入磁盘;对于静态资源或已知大小的 API,启用 proxy_cache 将结果缓存起来,后续请求直接从缓存读取,不再经过临时文件阶段;以及针对特定大文件传输场景,使用 proxy_request_buffering off 来禁用请求体的缓冲,虽然这主要影响上传,但也能间接反映缓冲策略的影响。
http {
# 全局启用代理缓存
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
server {
location /static/ {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# 命中缓存时直接返回,不经过 proxy_temp
add_header X-Cache-Status $upstream_cache_status;
}
location /api/large-upload {
# 禁用请求体缓冲,直接传递给后端
proxy_request_buffering off;
proxy_pass http://backend;
}
}
}
配置 proxy_cache 是最有效的长期解决方案。一旦缓存建立,重复的请求将直接从磁盘缓存读取,完全绕过 proxy_temp 目录。对于 /api/large-upload 这样的端点,禁用请求体缓冲意味着 Nginx 不会在本地保存上传的数据块,而是直接转发给后端,从而避免了上传过程中临时文件的堆积。结合监控工具(如 Prometheus + Grafana)监控 proxy_temp 目录的大小变化,可以及时发现配置不当或异常流量导致的磁盘占用飙升。











