r.maxmultipartmemory 控制 gin 解析 multipart 请求的内存缓冲上限(默认 32mb),超限直接报 http: request body too large,不进入 c.formfile;临时磁盘路径由 nginx 的 client_body_temp_path 配置,与 gin 无关。

gin.Default() 之后必须调用 r.MaxMultipartMemory
这个设置不是“指定临时目录”,而是控制 Gin 解析 multipart 请求时能用多少内存缓冲文件内容。它不涉及磁盘路径,只影响内存上限。默认值是 32 * 1024 * 1024(32 MiB),超过就直接拒绝请求,根本不会走到 c.FormFile() 这步。
常见错误是以为设大一点就能传大文件,结果上传失败时日志只有 http: request body too large,但 c.FormFile("file") 的 err 却是 nil——因为解析阶段已中断,压根没生成 FileHeader。
- 按业务最大单文件尺寸设,比如支持 100MB 视频,就写
r.MaxMultipartMemory = 100 * 1024 * 1024 - 不能设为
0(不限制),否则恶意上传可能耗尽服务内存 - 必须在
gin.Default()之后、注册任何路由之前调用,否则无效
真正要改“临时缓存目录”得靠 Nginx,不是 Gin
Gin 本身不管理磁盘级临时文件;它只处理已由 HTTP 服务器(如 Nginx)解析并传递过来的请求体。如果你用 Nginx 做反向代理,上传大文件时,Nginx 会先把超出内存缓冲的部分暂存到磁盘,这个位置才是你要配的“临时缓存目录”。
关键配置项是 client_body_temp_path,它和 Gin 无关,必须在 Nginx 配置里显式设置:
- 必须用绝对路径,例如
/data/nginx/client_body - 要确保 Nginx worker 进程用户(如
www-data)对该路径有读写权限:chown -R www-data:www-data /data/nginx/client_body - 推荐加两级子目录:
client_body_temp_path /data/nginx/client_body 1 2;,避免单目录文件过多 - 别和
proxy_temp_path共用同一磁盘,否则上传和后端响应争抢 I/O
为什么不能用相对路径或默认值?
Nginx 默认的临时路径(如 /var/cache/nginx/client_temp)往往在系统盘,小流量开发没问题,但生产环境上传频繁或文件较大时容易撑爆根分区,或因磁盘 I/O 瓶颈拖慢整个服务。
更隐蔽的风险是:你本地测试时一切正常,上线后才发现 client_body_temp_path 所在分区只有 5GB,而用户批量上传 200 个 50MB 文件,瞬间占满,后续所有上传请求都卡住或 500。
- 务必用独立挂载点(如 SSD 分区),并配合
noatime挂载参数 - 定期清理过期临时文件,可用
find /data/nginx/client_body -name "*.tmp" -mmin +60 -delete - 监控该路径磁盘使用率,阈值超 80% 就告警
c.SaveUploadedFile() 不经过“临时目录”,它直接写目标路径
很多人混淆了两个阶段:Nginx 接收并暂存请求体(client_body_temp_path),和 Gin 把已解析的文件保存到业务目录(如 ./uploads/)。后者完全绕过临时目录,是直接 os.Create() + io.Copy()。
所以 c.SaveUploadedFile(file, "./uploads/"+file.Filename) 失败,通常是因为:
-
./uploads/目录不存在(c.SaveUploadedFile不自动创建父目录) - 运行二进制时工作目录不是你预期的(systemd 启动默认工作目录是
/) - 用户上传的
file.Filename含../路径遍历,导致写入系统敏感路径(必须校验并清理文件名)
真正的临时缓存路径,只在 Nginx 层存在;Gin 层只有内存缓冲上限可调,没有磁盘临时目录的概念。











