上一篇 下一篇 分享链接 返回 返回顶部

Nginx 504 Gateway Timeout 是服务器问题吗?别急着升级,先把这几层查清楚

发布人:Minchunlin 发布时间:2026-05-02 09:19 阅读量:880


很多站长一看到网站打开提示 “504 Gateway Timeout”,第一反应就是:服务器是不是不行了?是不是 CPU 不够?是不是要升级香港服务器

但从我实际处理网站故障的经验来看,Nginx 504 不一定是服务器硬件问题。它更准确的意思是:Nginx 作为网关或反向代理,在规定时间内没有等到后端服务响应

也就是说,Nginx 本身还能工作,端口也可能正常,但它后面的 PHP、Java、Node.js、Python、数据库、接口服务、缓存服务,或者某个上游代理没有及时返回结果,最后 Nginx 只能给用户返回 504。

一、先说结论:504 是“后端响应超时”,不等于服务器宕机

Nginx 504 Gateway Timeout 常见在这些架构里:

用户浏览器

CDN / Cloudflare

Nginx

PHP-FPM / Node.js / Java / Python / 后端 API

MySQL / Redis / 第三方接口 / 文件存储

当用户访问页面时,Nginx 会把请求转发给后端程序。如果后端处理太慢,超过 Nginx 设置的等待时间,就会出现 504。

比如:

Nginx 等 PHP-FPM 返回结果,等了 60 秒还没回来
Nginx 等后端 Node.js 接口返回,等了 90 秒还没结果
Nginx 代理到另一台服务器,但对方网络或程序卡住

这时用户看到的是 504,但真正的问题可能在:

  • PHP-FPM 进程不够;
  • MySQL 慢查询卡住;
  • 后端程序死循环;
  • Redis 连接异常;
  • 上游接口太慢;
  • 磁盘 IO 被打满;
  • 服务器负载高;
  • 带宽不是瓶颈,但业务处理链路太慢。

所以,504 不是一句“服务器问题”就能概括的,它是一个链路问题。

二、504 和 502、503 有什么区别?

很多用户会把 502、503、504 混在一起,其实排查方向不一样。

错误码 通俗理解 常见原因
502 Bad Gateway 后端返回了异常响应,或者连接不上 PHP-FPM 挂了、端口错了、后端进程崩溃
503 Service Unavailable 服务暂时不可用 维护、限流、进程满载、服务不可用
504 Gateway Timeout 后端太久没响应 慢查询、程序卡住、上游接口慢、进程排队

简单说:

502 更像是“后端坏了或连不上”
503 更像是“后端暂时不接客”
504 更像是“后端处理太慢,Nginx 等不下去了”

所以遇到 504,不能只看 Nginx,也不能只看带宽,要顺着请求链路往后查。

三、哪些业务最容易出现 Nginx 504?

在香港服务器或海外服务器上,我见过比较容易触发 504 的业务主要有这几类。

1. WordPress / WooCommerce 网站

常见原因:

  • 插件太多;
  • 后台执行导入、采集、同步;
  • WooCommerce 订单查询慢;
  • wp-cron.php 被频繁触发;
  • 数据库 wp_options 表膨胀;
  • 页面未缓存,每次都动态生成。

比如一个 WordPress 外贸站,首页看起来只是普通页面,但实际加载时可能会执行:

主题函数
插件钩子
商品查询
文章查询
评论统计
会员状态判断
远程接口请求

任何一环慢了,都可能让 PHP 执行时间超过 Nginx 的等待时间。

2. 跨境电商后台和 ERP 接口

这类业务经常会调用外部接口,比如:

  • 支付接口;
  • 物流接口;
  • 库存同步接口;
  • 第三方 ERP;
  • 海外仓接口;
  • Shopify / Amazon / TikTok Shop API。

如果接口响应时间从 2 秒变成 30 秒,前端用户可能就直接看到 504。

这时候不是香港服务器带宽不够,而是后端业务依赖链路太长

3. 图片站、下载站、短视频站

这类网站容易在磁盘 IO 和后端处理上出问题。

比如:

  • 图片实时压缩;
  • 视频实时转码;
  • 文件权限校验;
  • 下载链接动态生成;
  • 大文件通过 PHP 中转下载;
  • 后台批量生成缩略图。

如果所有请求都走后端程序,而不是让 Nginx 直接处理静态文件,就很容易出现 504。

4. Java / Node.js / Python API 服务

API 服务出现 504,常见原因包括:

  • 后端线程池耗尽;
  • 数据库连接池打满;
  • 接口中调用了慢服务;
  • 代码里没有合理超时;
  • 单个请求占用时间太长;
  • 反向代理 timeout 设置过短。

比如 Nginx 代理到本地 Node.js:

location /api/ {
proxy_pass http://127.0.0.1:3000;
}

如果 Node.js 某个接口卡住 60 秒,Nginx 就可能返回 504。

四、先别急着改 Nginx timeout,第一步要看日志

很多人遇到 504 后,第一件事就是改:

proxy_read_timeout 300;
fastcgi_read_timeout 300;

这不是不能改,但如果问题根源是数据库慢查询、PHP 卡死、接口阻塞,只是把超时时间从 60 秒改到 300 秒,用户可能只是从“等 60 秒报错”变成“等 300 秒报错”。

正确做法是先看日志。

1. 查看 Nginx 错误日志

常见路径:

tail -f /var/log/nginx/error.log

如果是宝塔面板,一般可以在:

网站设置 → 日志

或服务器路径中查看对应站点日志。

重点看是否有类似内容:

upstream timed out (110: Connection timed out) while reading response header from upstream

这句话非常关键,意思是:

Nginx 已经把请求转给后端了,
但在读取后端响应头的时候超时了。

如果日志里出现:

connect() failed

那偏向后端服务连接不上。

如果出现:

upstream prematurely closed connection

那可能是后端进程提前断开、崩溃或被系统杀掉。

2. 查看访问日志,找出哪个 URL 超时

可以用:

tail -f /var/log/nginx/access.log

更建议在 Nginx 日志格式里加上请求耗时,例如:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" '
'request_time=$request_time '
'upstream_response_time=$upstream_response_time';

这样你就能看到:

request_time=65.231 upstream_response_time=65.230

如果某个接口经常超过 60 秒,那基本就能定位到业务 URL。

例如:

/wp-admin/admin-ajax.php
/api/order/sync
/product/export
/video/convert
/user/report/download

这种 URL 如果频繁超时,问题就不在 Nginx,而在后端业务逻辑。

五、服务器资源怎么查?不要只看 CPU

504 不一定是 CPU 高,也可能是内存、磁盘 IO、连接数或进程池排队。

1. 查看 CPU、内存、负载

top

或:

htop

重点看:

load average
CPU us / sy / wa
内存剩余
swap 是否大量使用

如果 CPU 不高,但 load 很高,要特别关注 wa,也就是 IO wait。

2. 查看磁盘 IO

iostat -x 1

如果看到:

%util 接近 100%
await 很高

说明磁盘响应很慢。很多网站 504 的根源并不是 CPU,而是数据库或日志写入把磁盘 IO 拖慢了。

这类情况在机械硬盘服务器、老旧 SATA SSD、日志量很大的站点上比较明显。

所以做数据库、电商、图片处理业务时,我更建议使用 NVMe SSD。

3. 查看网络连接数

ss -s

查看具体端口连接:

ss -antp | grep :80
ss -antp | grep :443
ss -antp | grep :9000

如果 PHP-FPM 使用 9000 端口,可以看是否存在大量连接堆积。

4. 查看 PHP-FPM 是否满了

如果是 PHP 网站,重点看 PHP-FPM 日志:

tail -f /var/log/php-fpm/error.log

或不同系统路径:

tail -f /var/log/php8.1-fpm.log
tail -f /var/log/php7.4-fpm.log

如果看到:

server reached pm.max_children setting

意思是 PHP-FPM 子进程已经用满,新的请求只能排队,排队时间长了就会 504。

这类问题在 WordPress、Discuz、Magento、Laravel 项目里很常见。

六、Nginx 504 常见原因和解决方案

原因一:PHP-FPM 进程数太少

如果服务器是 8 核 16G,但 PHP-FPM 只配置了 20 个子进程,高峰期请求一多,很容易排队。

可以检查 PHP-FPM 配置:

vim /etc/php/8.1/fpm/pool.d/www.conf

常见参数:

pm = dynamic
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
request_terminate_timeout = 120

参考建议:

服务器内存 PHP-FPM max_children 建议
4G 20 - 40
8G 40 - 80
16G 80 - 150
32G 150 - 300

但这里不能死套,要根据单个 PHP 进程实际占用内存计算。

比如:

ps -ylC php-fpm --sort:rss

如果单个 PHP-FPM 进程平均占用 80MB,服务器预留系统、MySQL、Redis 后还有 8GB 可用,那么:

8192MB ÷ 80MB ≈ 102

这时 pm.max_children 设置 80 - 100 比较合理。

原因二:MySQL 慢查询拖住后端

很多 504 最后都能查到数据库。

比如:

商品列表页打开慢
后台订单导出超时
用户中心加载慢
搜索接口卡住

可以开启 MySQL 慢查询日志:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;

查看慢查询日志:

tail -f /var/log/mysql/mysql-slow.log

重点关注:

Query_time
Rows_examined
Rows_sent

如果一个查询扫描了几十万行甚至几百万行,就要优化索引。

比如订单表:

SELECT * FROM orders WHERE user_id = 10086 ORDER BY created_at DESC LIMIT 20;

建议建立联合索引:

CREATE INDEX idx_user_created ON orders(user_id, created_at);

如果只是简单把 Nginx timeout 调大,数据库慢查询依然存在,高峰期只会把更多 PHP 进程拖死。

原因三:后端接口没有设置超时

很多程序员写接口时会调用第三方 API,但没有设置请求超时。

例如 PHP 里请求远程接口:

$response = file_get_contents("https://api.example.com/check");

如果对方接口卡住,PHP 请求也会跟着卡住。

更合理的做法是设置连接超时和读取超时,例如使用 curl:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/check");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 8);
$response = curl_exec($ch);
curl_close($ch);

这样第三方接口慢,不会把整个站点拖死。

原因四:大任务不应该同步执行

比如这些操作:

批量导出订单
批量生成缩略图
视频转码
邮件群发
数据采集
ERP 库存同步
大文件压缩
AI 推理任务

如果直接在用户请求里执行,很容易 504。

错误做法:

用户点击按钮 → PHP 开始导出 30 万条数据 → Nginx 等待 → 60 秒超时

正确做法:

用户点击按钮 → 创建任务 → 放入队列 → 后台慢慢执行 → 前端轮询进度 → 完成后下载

可以使用:

  • Redis Queue;
  • RabbitMQ;
  • Laravel Queue;
  • Celery;
  • Supervisor;
  • systemd 定时任务;
  • Cron 后台任务。

这类改造比单纯升级服务器更有效。

原因五:Nginx timeout 配置太短

如果后端确实需要较长处理时间,比如后台导出、内部管理接口,可以适当增加 Nginx 超时时间。

反向代理场景:

location /api/ {
proxy_pass http://127.0.0.1:3000;

proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 120s;
}

PHP-FPM 场景:

location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

fastcgi_connect_timeout 10s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 120s;
}

但我一般不建议一上来就设置成 600 秒、900 秒。因为这样会让问题隐藏得更深。

比较合理的策略是:

普通页面:30 - 60 秒
后台导出:120 - 300 秒
内部任务接口:单独 location 配置
前台用户访问页面:尽量控制在 1 - 3 秒内响应

七、不同服务器配置下,504 的处理思路不一样

很多用户问:504 是不是该升级服务器?我的看法是:要先看瓶颈在哪里,再决定升 CPU、内存、硬盘还是带宽。

下面用几个香港服务器配置举例。

配置一:入门型香港服务器

适合小型企业站、WordPress 展示站、轻量后台。

CPU:Intel Xeon E3 / E-2334 级别
内存:16GB DDR4
硬盘:480GB SSD / 960GB SSD
带宽:100M BGP,含 25M CN2 直连
系统:Ubuntu 22.04 / CentOS 7.x
适合:企业官网、外贸展示站、小型 WordPress

这类配置如果出现 504,优先查:

WordPress 插件
PHP-FPM max_children
MySQL 慢查询
是否开启页面缓存
是否有异常爬虫

不一定马上换机器。很多小站 504 是插件、数据库或缓存问题。

配置二:高性能香港服务器

适合跨境电商、会员系统、接口站、图片站。

CPU:AMD EPYC 4585PX,16核32线程
内存:64GB DDR5
硬盘:960GB NVMe PCIe Gen4 SSD
带宽:100M BGP,含 25M CN2 直连
系统:Ubuntu 22.04 / Debian 12
适合:WordPress + WooCommerce、Laravel、API 服务、企业后台

这类配置 CPU 单核和多核都比较强,如果还频繁 504,就要重点查:

数据库索引是否合理
PHP-FPM 是否被打满
Redis 是否正常
后台任务是否同步执行
是否存在大量慢接口
磁盘 IO 是否异常

对于 WooCommerce、Laravel、ThinkPHP、Java API 这类业务,64GB 内存可以给 MySQL、Redis、PHP-FPM 留出更大的空间,比 16GB 配置稳定很多。

配置三:数据库 / 高并发型香港服务器

适合数据库独立部署、订单系统、数据量较大的业务。

CPU:AMD EPYC 7402P,24核48线程
内存:128GB DDR4
硬盘:2 × 1.92TB NVMe SSD
带宽:100M BGP / 可升级 1G 国际带宽
系统:Ubuntu 22.04 / Rocky Linux 9
适合:MySQL 独立服务器、ERP、订单系统、日志分析、内部 API

如果数据库压力大,建议把架构拆成:

Web 服务器:Nginx + PHP-FPM / Java / Node.js
数据库服务器:MySQL / MariaDB / PostgreSQL
缓存服务器:Redis

这样 504 的排查会更清晰,也能避免 Web 和 MySQL 抢 CPU、内存、磁盘 IO。

配置四:视频 / 图片处理型香港 GPU 服务器

适合短视频、图片处理、AI 推理、转码业务。

CPU:2 × AMD EPYC 7303
内存:64GB DDR4
硬盘:960GB NVMe PCIe Gen4 SSD
显卡:RTX 4090 / RTX 5090 / A100 可选
带宽:100Mbps 混合带宽,含 25Mbps CN2
系统:Ubuntu 22.04
适合:视频转码、AI 推理、图片识别、模型接口

这类业务最容易因为“同步执行重任务”导致 504。

比如:

用户上传视频 → 服务器马上转码 → 浏览器等待 → Nginx 504

正确架构应该是:

上传文件 → 返回任务 ID → 后台队列转码 → 前端查询进度 → 完成后播放

GPU 服务器不是让用户请求一直等 GPU 算完,而是要配合任务队列使用。

八、推荐的 Nginx + PHP-FPM 优化配置

下面给一个适合 WordPress / PHP 网站的参考方向。

Nginx 站点配置示例

server {
listen 80;
server_name example.com;
root /www/wwwroot/example.com;
index index.php index.html;

client_max_body_size 100m;
keepalive_timeout 30;

location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_connect_timeout 10s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 120s;

fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
}

location ~* \.(jpg|jpeg|png|gif|css|js|ico|webp|svg|woff2)$ {
expires 30d;
access_log off;
}
}

这里重点不是无限拉长超时,而是:

静态资源交给 Nginx 直接处理
PHP 请求才交给 PHP-FPM
适当增加 fastcgi_read_timeout
合理设置 buffer

PHP-FPM 配置示例

假设服务器为:

CPU:16核32线程
内存:64GB
业务:WordPress + WooCommerce

可以参考:

pm = dynamic
pm.max_children = 120
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 40
pm.max_requests = 1000
request_terminate_timeout = 120

同时开启慢日志:

request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log

这样哪个 PHP 脚本执行慢,就可以通过 slowlog 追踪。

九、MySQL 优化不能忽略,否则 Nginx 怎么调都没用

很多用户调了 Nginx、调了 PHP-FPM,504 还是反复出现,最后发现 MySQL 才是根源。

1. 开启慢查询日志

slow_query_log = 1
long_query_time = 2
slow_query_log_file = /var/log/mysql/mysql-slow.log

2. 检查是否缺少索引

常见问题:

订单表按用户 ID 查询没有索引
文章表按分类查询没有索引
商品表按状态筛选没有索引
日志表数据量太大没有归档

3. 分离大表和日志表

对于电商和 API 业务,日志表、访问记录表、订单流水表不能无限增长。

建议:

访问日志定期归档
订单流水按月份分表或归档
后台报表异步生成
搜索功能交给 Elasticsearch / Meilisearch
热点数据放 Redis

否则服务器配置再高,也可能被几条慢 SQL 拖垮。

十、如果用了 CDN 或 Cloudflare,也可能看到 504

如果网站前面套了 CDN,用户看到的 504 可能来自两种情况:

CDN 等源站超时
Nginx 等后端超时

排查时要分清楚:

1. 直接访问源站 IP 测试

可以临时绑定 hosts:

源站IP example.com

然后绕过 CDN 访问网站。

如果绕过 CDN 仍然 504,说明问题在源站。

如果绕过 CDN 正常,而 CDN 访问 504,可能是:

CDN 到源站线路不稳定
CDN 回源超时太短
源站防火墙拦截 CDN IP
SSL 回源配置异常
源站响应头太慢

十一、什么时候才需要升级服务器?

出现 504 后,不是不能升级服务器,而是要看是否满足这些条件。

适合升级服务器的情况

如果你看到:

CPU 长时间 90% 以上
内存长期不足并大量使用 swap
磁盘 IO util 接近 100%
MySQL 占用资源过高
PHP-FPM 进程长期打满
高峰期连接数明显超过当前配置承载能力

这时候升级服务器是有意义的。

比如从:

4核8G SSD

升级到:

AMD EPYC 4585PX 16核32线程
64GB DDR5
960GB NVMe PCIe Gen4 SSD
100M BGP + 25M CN2

对 PHP 动态处理、数据库查询、后台任务并发都会有明显改善。

不适合只靠升级解决的情况

如果问题是:

SQL 没索引
插件写得差
接口没有超时
任务同步执行
PHP 代码死循环
第三方 API 慢
Nginx 配置错误

那升级服务器只能暂时缓解,不能根治。

比如一个慢 SQL 原来执行 80 秒,换更强服务器后可能变成 30 秒,看起来好了,但高峰期请求一多,还是会 504。

十二、我建议的标准排查流程

遇到 Nginx 504,可以按这个顺序查:

第一步:看 Nginx error.log,确认是否 upstream timed out
第二步:看 access.log,找出具体超时 URL
第三步:看 PHP-FPM / Java / Node.js 后端日志
第四步:看 CPU、内存、load、IO wait
第五步:看 MySQL 慢查询日志
第六步:看是否有第三方接口、远程 API、文件存储超时
第七步:优化程序、SQL、队列、缓存
第八步:最后再调整 Nginx timeout 和升级服务器

不要一上来就改:

fastcgi_read_timeout 600;
proxy_read_timeout 600;

这只能让问题晚一点暴露。

十三、不同业务的处理建议

WordPress 网站

建议:

开启页面缓存
减少重型插件
禁用不必要的 wp-cron
优化 wp_options 表
PHP-FPM 开启 slowlog
MySQL 开启慢查询
图片交给对象存储或 CDN

服务器建议:

16核32线程 CPU
32GB - 64GB 内存
NVMe SSD
100M BGP + 25M CN2

适合外贸站、企业站、WooCommerce 商城。

电商 / ERP / 后台系统

建议:

订单导出异步化
库存同步队列化
接口设置超时
数据库加索引
Redis 缓存热点数据
Web 和数据库分离

服务器建议:

Web:AMD EPYC 4585PX / 64GB / NVMe
DB:AMD EPYC 7402P / 128GB / 双 NVMe
带宽:100M BGP 起步,可按业务升级

视频 / 图片处理业务

建议:

上传和处理分离
转码任务放队列
缩略图后台生成
静态资源走 Nginx 或对象存储
避免 PHP 中转大文件

服务器建议:

CPU:双路 AMD EPYC
内存:64GB 起步
硬盘:NVMe SSD
显卡:RTX 4090 / A100 按任务选择
带宽:按分发需求选择 100M、1G 或更高

十四、504 不一定是服务器差,而是链路里有地方“等太久”

Nginx 504 Gateway Timeout 的本质不是“网站打不开”这么简单,而是:

Nginx 正常收到请求
也正常转发给后端
但后端没有在规定时间内返回结果

所以它可能是服务器资源问题,也可能是程序、数据库、接口、队列、缓存、CDN 回源等问题。

我的建议是:

小站先查插件、PHP-FPM、MySQL 慢查询;
电商站重点查订单、库存、接口和数据库;
图片视频站重点查 IO、转码和任务队列;
API 服务重点查连接池、线程池和超时控制;
高并发业务再结合服务器硬件升级。

如果服务器本身配置偏低,比如 2核4G、4核8G,还要跑 WordPress、电商、数据库、缓存和后台任务,那遇到 504 很正常。
但如果已经是香港高性能物理服务器,比如 AMD EPYC 4585PX / 64GB 内存 / NVMe SSD / 100M BGP + 25M CN2,仍然频繁 504,就更应该深入检查程序和数据库,而不是只盯着带宽或 Nginx 配置。

一句话概括:

504 不是让你马上升级服务器,而是提醒你:Nginx 后面的某个环节已经慢到让用户等不下去了。

目录结构
全文