使用 Codex 给项目增加文件上传功能以后,经常会出现一种很典型的情况:
小文件上传完全正常,文件稍微大一点就开始失败。
常见表现包括:
- 1MB文件可以上传,20MB就失败;
- 本地正常,部署到服务器后报错;
- 浏览器上传一段时间后突然中断;
- 后端日志里根本看不到请求;
- 出现
413 Request Entity Too Large; - 应用已经调大上传限制,但线上还是失败;
- 文件越大,越容易出现超时或者连接断开。
这类问题很多时候不是上传代码本身写错了。
真正的问题是:
一个文件从浏览器到最终存储,中间可能经过多层,每一层都可能有自己的大小和超时限制。
一、先看错误发生在哪一层
文件上传的真实链路通常不是:
前端 → 后端
这么简单。
更常见的是:
浏览器 → Nginx / Gateway → Web框架 → Multipart解析 → 临时目录 → 最终存储
所以大文件失败时,第一步不是继续修改上传接口。
应该先判断:
请求到底有没有到达后端。
如果后端完全没有收到请求,问题通常更靠前。
如果后端已经开始处理,然后中途失败,就继续检查应用层和存储层。
二、413通常先查代理层限制
如果出现:
413 Request Entity Too Large
通常意味着请求体大小超过了某一层的限制。
例如项目使用 Nginx,可能配置了请求体最大大小。
如果代理层只允许10MB,那么即使后端允许100MB:
20MB文件仍然根本到不了应用。
所以不要只修改Java、Node或者Python里的上传配置。
还要检查:
- Nginx;
- API Gateway;
- Ingress;
- 云负载均衡;
- 反向代理。
中间任何一层限制更小,最终都以最小值为准。
三、Web框架自己也可能限制Multipart大小
即使请求已经通过Nginx,Web框架还可能继续检查。
不同技术栈通常都有自己的上传限制。
例如可能限制:
- 单个文件大小;
- 整个请求大小;
- Multipart表单大小;
- 请求Body大小。
所以有时候会出现:
Nginx已经调到100MB,上传50MB还是失败。
这时候应该继续检查应用框架配置。
关键是区分:
代理允许多大
和
应用允许多大。
这不是同一个配置。
四、单文件限制和整个请求限制也不一样
假设项目规定:
- 单个文件最大20MB;
- 整个请求最大30MB。
用户一次上传两个18MB文件。
每个文件单独都没有超过20MB,但总请求已经达到36MB。
结果还是失败。
所以排查时要同时确认:
单文件限制
和
总Body限制。
尤其是多文件上传场景,这一点很容易被忽略。
五、文件越大,越容易暴露超时问题
有些大文件不是立即失败,而是:
上传一段时间后突然断开。
这种情况就不一定是大小限制,也可能是超时。
例如:
- 客户端请求超时;
- Nginx读取超时;
- Gateway超时;
- 后端处理时间过长;
- 上传到对象存储时间过长。
小文件几秒就传完,所以看不出问题。
大文件需要几十秒甚至几分钟,才会触发这些限制。
所以如果错误表现是:
不是马上报错,而是等一段时间后失败。
就应该重点检查:
Timeout,而不仅是Body Limit。
六、不要把整个大文件一次性读进内存
Codex实现上传功能时,有时会采用:
先把文件全部读入内存,再继续处理。
小文件看起来没有问题。
但文件一大,就可能导致:
- 内存占用快速增加;
- GC压力上升;
- 服务变慢;
- 容器OOM;
- 多人同时上传时直接崩溃。
因此大文件上传更适合考虑:
流式处理
或者:
临时文件
而不是一直把完整文件保存在内存里。
所以看到大文件失败,也要确认失败是不是来自:
内存限制。
七、临时目录同样可能成为瓶颈
Multipart框架有时会先把上传内容写入临时目录。
这时候还要检查:
- 临时目录是否存在;
- 是否有写权限;
- 磁盘空间是否足够;
- 容器临时空间是否有限;
- 文件系统是否有配额。
例如本地磁盘空间很大,所以正常。
到了Docker或者服务器环境,临时目录只有很小空间。
于是:
小文件正常,大文件失败。
这类问题仅修改上传大小限制也解决不了。
八、线上失败、本地正常时重点看中间层
如果本地直接访问后端:
50MB上传成功
但部署以后通过正式域名:
50MB失败
那就应该优先怀疑:
- Nginx;
- CDN;
- Gateway;
- Ingress;
- 云平台限制。
可以分别测试:
直接请求后端地址
和
通过外部域名请求。
如果前者成功、后者失败,问题基本就在中间链路。
这样比继续修改业务接口效率高很多。
九、浏览器端也要确认真实错误
前端页面可能只显示一句:
上传失败。
这条信息太少。
应该继续查看浏览器 Network:
- HTTP状态码是多少;
- 请求是否真正发出;
- 上传到多少百分比失败;
- 服务端返回了什么;
- 是413、502、504还是连接中断。
不同错误对应的排查方向完全不同。
比如:
413 更像大小限制;
504 更像网关超时;
500 更可能已经进入应用内部。
所以第一步应该尽量拿到:
真实状态码和响应信息。
十、大文件最好考虑专门的上传方案
如果系统未来需要经常上传:
几百MB甚至更大的文件
单纯不断提高Body Limit并不一定是最好的方案。
这时可以考虑:
- 分片上传;
- 断点续传;
- 浏览器直接上传对象存储;
- 预签名URL;
- 后端只负责生成上传凭证和保存文件元数据。
因为文件越大,让它完整经过应用服务器:
占连接、占带宽、占内存、占处理时间
的问题都会越来越明显。
十一、可以按这个顺序排查
Codex新增文件上传后,小文件正常、大文件失败,可以依次检查:
第一步:看HTTP状态码。
先判断是413、500、502、504还是其他错误。
第二步:确认请求有没有到后端。
后端日志里有没有收到。
第三步:检查Nginx / Gateway的Body限制。
代理层是不是先拦住了。
第四步:检查Web框架Multipart限制。
单文件和总请求限制都确认。
第五步:检查超时。
是不是上传时间过长导致连接被断开。
第六步:检查内存和临时目录。
有没有OOM、磁盘不足或者权限问题。
第七步:再决定是否需要分片或直传对象存储。
不要一开始就盲目把所有限制都调得特别大。
十二、可以直接让Codex这样排查
以后遇到类似问题,可以直接告诉Codex:
请不要先继续修改上传业务逻辑。先确认大文件失败时的HTTP状态码和请求链路,检查Nginx、Gateway、Web框架的Body和Multipart限制,再检查上传超时、内存占用、临时目录和磁盘空间。分别测试直连后端和经过正式域名的上传结果,最后指出限制具体发生在哪一层。
这样比简单说:
把最大上传限制调大一点。
更容易找到真正原因。
最后
Codex新增文件上传以后,小文件正常、大文件总失败,很多时候不是:
上传功能没写好。
而是:
整个上传链路里有一层限制比你想象得更小。
真正稳妥的排查方式应该是:
浏览器 → Nginx / Gateway → Web框架 → Multipart → 临时目录 → 存储
逐层确认。
尤其要记住:
应用层允许100MB,不代表整个系统就真的能上传100MB。
只有整条链路的限制、超时和资源配置都匹配,大文件上传才能真正稳定。
持续更新 Codex、大模型开发与 AI 编程实战内容,更多技术内容和稳定订阅渠道欢迎搜索关注「仙逆GPT」。