后台导入几千行数据,进度条走到一半页面变成 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 的还是云厂商返回的,两者的处理位置完全不同。
调整超时只是让请求等更久,不解决根本问题。先把任务拆小、加进度反馈,再考虑放宽超时,否则并发一高,长时间占用的连接会把连接池拖垮。