当遇到 504 Gateway Time-out 错误时,通常是因为 Nginx 作为反向代理等待后端服务(如 PHP-FPM、Java 应用等)响应的时间超过了预设的超时阈值。以下是详细的解决方案,结合知识库中的信息整理而成:
后端服务响应过慢:后端程序(如 PHP、Java 应用)处理时间超过 Nginx 的超时时间。
数据库查询缓慢、外部接口调用超时、死循环或资源竞争等问题导致程序卡顿。
网络问题:Nginx 与后端服务之间的网络不稳定或带宽不足。
配置不当:Nginx 或后端服务(如 PHP-FPM)的超时参数设置过小。
在 Nginx 配置文件中(通常位于 /etc/nginx/nginx.conf
或站点配置文件 /etc/nginx/conf.d/*.conf
),根据后端服务类型调整以下参数:
proxy_pass
(如反向代理到 Java、Node.js 等)http {
# 全局配置(可选)
proxy_connect_timeout 300; # 连接后端的超时时间(秒)
proxy_send_timeout 300; # 发送请求给后端的超时时间
proxy_read_timeout 300; # 读取后端响应的超时时间
proxy_buffer_size 128k; # 缓冲区大小
proxy_buffers 4 256k; # 缓冲区数量和大小
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_server; # 后端服务地址
# 单独覆盖该 location 的超时配置
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}
}
}
fastcgi_pass
(如 PHP-FPM)http {
# 全局配置(可选)
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
server {
listen 80;
server_name example.com;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php-fpm.sock; # 或 IP:端口
fastcgi_index index.php;
# 单独覆盖超时配置
fastcgi_read_timeout 300;
}
}
}
说明:将 300
替换为实际需要的超时时间(单位:秒)。如果后端服务响应时间更长,可进一步增大数值(如 600
秒)。
重启 Nginx 生效:
sudo systemctl restart nginx # 或
sudo service nginx reload
如果后端是 PHP-FPM,需调整其配置以避免进程不足或超时:
调整 php-fpm
的进程数:根据服务器内存调整 max_children
参数(路径:/etc/php/7.x/fpm/pool.d/www.conf
或 /etc/php-fpm.conf
):
pm = dynamic # 动态调整进程数
pm.max_children = 50 # 最大进程数(根据内存调整)
pm.start_servers = 5 # 启动时的进程数
pm.min_spare_servers = 3
pm.max_spare_servers = 35
增加 PHP 脚本执行时间:在 php.ini
中设置:
max_execution_time = 300 # PHP 脚本最大执行时间(秒)
request_terminate_timeout = 300 # PHP-FPM 请求终止时间
sudo systemctl restart php7.4-fpm # 根据 PHP 版本调整
如果超时是由于程序逻辑或数据库查询导致的,需针对性优化:
检查慢查询:使用 EXPLAIN
分析 SQL 语句,添加索引。避免在循环中执行数据库查询。
避免长时间阻塞操作:将耗时任务(如文件处理、大数据计算)改为异步处理(如通过队列系统)。使用缓存减少重复计算。
网络稳定性:使用 ping
、traceroute
检查 Nginx 与后端服务之间的网络延迟。确保防火墙未阻止相关端口(如 PHP-FPM 的 9000 端口)。
服务器资源监控:使用 top
、htop
、free -m
检查 CPU、内存、磁盘 IO 是否过载。如果资源不足,考虑升级配置或优化代码。
/var/log/nginx/error.log
):tail -f /var/log/nginx/error.log
关键信息示例:
2023/11/03 12:34:56 [error] 1234#5678: *9 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.1.100, server: example.com, request: "GET /api/long-task HTTP/1.1", upstream: "http://127.0.0.1:8080/api/long-task", host: "example.com"
PHP:检查 /var/log/php7.4-fpm.log
或自定义日志。
数据库:查看慢查询日志(如 MySQL 的 slow_query_log
)。
负载均衡:使用 upstream
模块将请求分发到多个后端服务器。
缓存:对频繁访问的接口启用 Nginx 缓存或 CDN 缓存。
检查 Nginx 配置语法:
sudo nginx -t
模拟长请求测试:使用 curl
或 Postman 发送一个耗时请求,观察是否仍出现 504 错误。
问题类型 | 解决方案 |
---|---|
Nginx 超时配置过小 | 调整 proxy_read_timeout 、fastcgi_read_timeout 等参数 |
后端进程不足 | 调整 PHP-FPM 的 max_children |
数据库/代码性能问题 | 优化 SQL、减少阻塞操作、异步化任务 |
网络不稳定 | 检查防火墙、带宽、DNS 解析 |
资源不足 | 升级服务器配置或优化资源使用 |
通过以上步骤,应能有效解决 504 Gateway Time-out 问题。若问题仍存在,建议结合具体日志进一步排查。