后台导入几千行数据,进度条走到一半页面变成 504。请求本身没失败,是网关等太久主动断开了连接。

先看是哪一层的超时

tail -n 20 /var/log/nginx/error.log

日志里出现 upstream timed out 就是 Nginx 等 PHP 太久。如果日志里没有,说明 PHP 自己先超时退出,返回的是 500 或空白页。

Nginx 侧调整

fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
client_max_body_size 64m;

放在对应的 location 或 server 块里,执行 nginx -t 后重载。client_max_body_size 不调的话,大文件会直接返回 413,而不是 504。

PHP 侧同步放开

max_execution_time = 300
max_input_time = 300
post_max_size = 64M
upload_max_filesize = 64M

改完重启 PHP-FPM 才生效。两边的数值要匹配,只改一边还是会在另一处断掉。

如果任务本身要跑十几分钟,更合理的是转成队列异步处理,页面立即返回任务编号,前端轮询进度。长时间占用一个请求,体验和稳定性都差。

别忘了对象存储和 CDN 也能超时

上传走 CDN 或对象存储时,链路里还有一层自己的超时配置。看到 504 先确认报错页面是 Nginx 的还是云厂商返回的,两者的处理位置完全不同。

调整超时只是让请求等更久,不解决根本问题。先把任务拆小、加进度反馈,再考虑放宽超时,否则并发一高,长时间占用的连接会把连接池拖垮。

作者 9823189