返回博客列表

CDN出现502、503、504怎么办?先判断节点、回源还是源站故障

CdnChart 技术团队发布于 2026-09-2012 分钟阅读
CDN出现502、503、504怎么办?先判断节点、回源还是源站故障

网站接入CDN以后,偶尔出现502、503或504,页面看起来都差不多:打不开、加载失败,或者只显示一行英文错误。

但这三个状态码表达的意思并不相同。

  • 502更像是:CDN联系上游时,收到了一份无法正常使用的响应。

  • 503更像是:当前这台服务器暂时没有能力处理请求。

  • 504更像是:CDN一直在等上游响应,但等到超时也没有拿到结果。

按照HTTP规范,502表示网关或代理收到了无效的上游响应;503表示服务因为过载或维护暂时不可用;504表示代理没有及时收到上游服务器的响应。

真正排查时,不能只看到“5xx”就笼统地检查服务器。更有效的方法是先弄清楚:

这个状态码是谁返回的,CDN节点、源站Web服务器,还是网站程序?

先用一张表分清502、503和504

状态码

通常代表什么

最先检查什么

502 Bad Gateway

CDN收到了异常或无效的上游响应

回源协议、TLS握手、连接重置、响应头格式

503 Service Unavailable

CDN或源站当前无法处理请求

服务器负载、维护状态、限流、健康检查

504 Gateway Timeout

CDN等待上游响应超时

源站响应时间、数据库、接口调用、回源超时设置

这张表只能帮助确定排查方向,不能直接认定责任在CDN还是源站。

同一个502页面,可能是CDN边缘节点生成的,也可能是源站Nginx返回的;同一个503,也可能来自CDN限流、源站维护页或者应用程序主动拒绝服务。

排查前先保存完整响应

不要只截一张浏览器错误页面。

先用curl保存响应头和响应内容:

curl -sS -D cdn-headers.txt \
  -o cdn-body.html \
  https://www.example.com/problem-path

也可以直接在终端查看:

curl -sS -D - -o /dev/null \
  https://www.example.com/problem-path

重点记录这些内容:

HTTP状态码
Date
Server
Via
Age
Retry-After
X-Cache
CF-Cache-Status
X-Request-ID
CDN厂商自定义请求ID

不同CDN使用的响应头并不相同,不能看到Server字段就马上下结论。不过,边缘节点编号、请求ID、缓存状态和错误页面样式,通常可以帮助判断响应来自哪一层。

如果故障不是一直出现,还要记下准确时间、访问地区、运营商和节点IP。没有时间和请求ID,CDN厂商很难从海量日志中找到对应请求。

502:先查CDN有没有收到“异常的源站响应”

502的重点不是“慢”,而是CDN作为代理访问上游时,拿到的响应不符合预期。

MDN对502的解释是:代理或网关从上游服务器收到了无效响应;如果一直没有收到上游响应,更接近504。

常见原因包括:

  • 源站主动重置连接

  • 源站进程崩溃或提前关闭连接

  • CDN使用HTTPS回源,但源站只支持HTTP

  • 源站HTTPS证书、SNI或TLS版本不兼容

  • CDN回源端口配置错误

  • 源站返回了不完整或格式异常的HTTP响应头

  • Nginx、Apache与应用服务器之间连接失败

  • PHP-FPM、Node.js、Java等后端进程退出

  • 源站防火墙拦截了CDN回源IP

  • CDN回源到了错误的服务器

看到502,先做源站绕过测试

假设:

加速域名:www.example.com
源站IP:203.0.113.10

可以通过curl --resolve绕过CDN,同时保留正确的Host和HTTPS SNI:

curl -sS -D - -o /dev/null \
  --resolve www.example.com:443:203.0.113.10 \
  https://www.example.com/problem-path

再测试经过CDN的结果:

curl -sS -D - -o /dev/null \
  https://www.example.com/problem-path

如果绕过CDN返回200,经过CDN返回502,优先检查:

  • CDN回源协议是不是配错了

  • 回源端口是否正确

  • 回源Host与SNI是否一致

  • 防火墙是否只允许部分CDN节点

  • CDN是否回源到了其他IP

  • 源站是否限制了CDN节点的TLS版本或加密套件

如果绕过CDN同样返回502,就要继续查看源站Nginx、Apache、负载均衡器和应用进程之间的连接。

例如Nginx日志中可能出现:

upstream prematurely closed connection
connection reset by peer
no live upstreams
SSL_do_handshake() failed
connect() failed

这些日志比浏览器里的一句“502 Bad Gateway”更有价值。

502不要只检查CPU

很多502并不是服务器负载过高,而是回源协议或连接出了问题。

例如CDN配置为:

HTTPS回源:443端口

但源站实际只监听:

HTTP:80端口

这种情况下,即使源站CPU只有5%,CDN仍然可能返回502。

所以看到502时,先检查“连接是否正确建立、响应是否完整”,再检查服务器性能。

503:先判断是谁暂时拒绝了请求

503表示服务当前没有能力处理请求,常见于临时过载、系统维护、限流或没有可用后端。

服务器还可以通过Retry-After响应头告诉客户端多久以后再试。

例如:

HTTP/1.1 503 Service Unavailable
Retry-After: 120

这表示服务建议客户端120秒后重新请求。

但实际环境里的503来源很多,至少要区分下面三种情况。

CDN节点返回503

如果错误页面明显带有CDN品牌,或者响应头包含边缘节点请求ID,503可能来自CDN自身。

常见原因包括:

  • CDN边缘节点临时过载

  • 某一区域节点故障

  • CDN安全策略或限流规则触发

  • CDN无法找到健康源站

  • 边缘函数执行失败

  • 账户套餐、请求量或资源额度受限

这种情况下,要观察问题是否只出现在部分地区或部分运营商。

可以使用CDNChart的网站测速工具,从不同地区和网络测试同一个URL。如果只有少数地区出现503,而其他地区正常,问题更可能集中在区域节点、调度或配置同步上。

源站Web服务器返回503

Nginx、Apache、IIS或源站负载均衡器也可能返回503。

常见情况包括:

  • 没有健康的后端服务器

  • PHP-FPM进程池已满

  • 应用服务全部下线

  • 服务器正在维护

  • 并发连接数达到上限

  • 反向代理主动执行限流

  • 容器或服务实例还没准备好

如果负载均衡器后面有多个源站,应分别测试每个源站:

curl -sS -D - -o /dev/null \
  --resolve www.example.com:443:203.0.113.10 \
  https://www.example.com/problem-path
curl -sS -D - -o /dev/null \
  --resolve www.example.com:443:203.0.113.20 \
  https://www.example.com/problem-path

如果一个源站返回200,另一个返回503,通常是后端实例状态或健康检查出现了问题,不应该继续盲目刷新CDN缓存。

网站程序主动返回503

WordPress、Java、Node.js、PHP以及各种网站框架,也可能主动返回503。

例如:

  • 网站进入维护模式

  • 数据库连接池已满

  • 应用队列积压

  • 外部依赖不可用

  • 接口触发频率限制

  • 程序检测到服务未准备完成

  • 部署过程中实例暂时下线

此时Web服务器可能运行正常,但应用日志中会出现异常。

503尤其需要同时检查:

CPU和内存
磁盘空间与磁盘IO
进程数量
数据库连接数
应用线程池
容器健康状态
请求限流规则
依赖服务状态

不要只看服务器是否“在线”。服务器能Ping通、SSH能登录,不代表应用仍有能力处理HTTP请求。

504:先查请求卡在哪里,而不是马上增加超时时间

504说明CDN或其他代理已经向上游发出请求,但没有在规定时间内拿到响应。

它和502最直观的区别是:

  • 502:上游返回了异常响应,或者连接异常终止。

  • 504:代理等了很久,仍然没有及时得到响应。

MDN也将504描述为代理或网关未能及时从上游服务器获得响应。

常见原因包括:

  • 源站处理请求太慢

  • 数据库查询耗时过长

  • 接口调用第三方服务超时

  • 动态页面生成时间太长

  • 文件上传或下载超过CDN限制

  • 源站连接数已满

  • 防火墙丢弃连接而不是明确拒绝

  • CDN到源站网络质量异常

  • 回源超时时间设置过短

  • 应用出现死锁或任务阻塞

用curl判断慢在连接还是响应

下面这条命令可以拆分一次请求的主要耗时:

curl -sS -o /dev/null \
  -w 'DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\nStatus: %{http_code}\n' \
  https://www.example.com/problem-path

输出可能类似:

DNS: 0.012s
Connect: 0.048s
TLS: 0.103s
TTFB: 30.001s
Total: 30.001s
Status: 504

DNS、TCP和TLS都很快,但首字节等待了30秒,说明问题很可能出在回源后的处理阶段,例如应用、数据库或外部接口。

time_starttransfer包含连接准备时间以及服务器生成响应所需的时间,具体定义可以参考curl官方手册

还应绕过CDN测试源站:

curl -sS -o /dev/null \
  --resolve www.example.com:443:203.0.113.10 \
  -w 'TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\nStatus: %{http_code}\n' \
  https://www.example.com/problem-path

如果源站本身就需要35秒才能响应,而CDN回源超时是30秒,那么504并不意外。

不要先把超时从30秒改成300秒

增加回源超时时间有时能让请求完成,但它也可能掩盖真正的问题。

如果一个普通页面需要几十秒才能生成,应该先检查:

  • 是否存在慢SQL

  • 数据库是否被锁

  • 应用线程是否阻塞

  • 外部API是否响应缓慢

  • 页面是否执行了大量同步任务

  • 是否把导出、转码等耗时操作放在同步请求中

  • 是否缺少应用缓存

  • 是否发生连接池耗尽

对于报表生成、视频处理、大文件导出等长任务,更合理的方式通常是异步处理:先返回任务编号,处理完成后再让用户下载结果,而不是让CDN连接一直等待。

如何判断错误在CDN还是源站

可以把经过CDN和绕过CDN的结果放在一起比较:

CDN结果

源站结果

优先排查方向

502

200

回源协议、端口、Host、SNI、防火墙

502

502

源站代理、应用进程、上游连接

503

200

CDN节点、限流、健康检查、边缘规则

503

503

服务器负载、维护模式、应用容量

504

源站响应很慢

应用、数据库、外部接口

504

源站响应正常

CDN到源站网络、回源超时、源站IP选择

部分地区5xx

其他地区正常

区域节点、运营商线路、配置同步

偶发5xx

重试后正常

多源站不一致、瞬时过载、连接池问题

如果还不确定域名当前经过哪家CDN,可以先使用CDNChart的CDN检测工具,检查CNAME、节点IP和CDN识别结果。

只有部分URL报错时,别先查整台服务器

如果首页正常,只有某个API返回504,说明基础网络和CDN接入大概率仍然正常。

这时应该重点检查该URL对应的业务逻辑:

/api/search
/api/export
/api/payment/callback
/report/download

可能只有这些请求会执行慢查询、访问第三方接口或者生成大文件。

同样,如果静态资源正常、动态页面503,也不能简单判断为CDN节点故障。静态资源可能直接命中边缘缓存,根本没有访问源站;动态页面则每次都需要回源。

排查时应分别选择:

  • 一个稳定命中缓存的静态文件

  • 一个普通动态页面

  • 一个发生故障的具体接口

分别测试后,才能看出问题位于缓存层、回源链路还是应用层。

偶发故障要连续测,不要只刷新一次

502、503和504经常不是持续出现,而是“十次里失败两次”。

可以连续请求并输出状态码、节点IP和耗时:

for i in $(seq 1 10); do
  curl -sS -o /dev/null \
    -w "$(date '+%F %T') status=%{http_code} remote=%{remote_ip} connect=%{time_connect} ttfb=%{time_starttransfer} total=%{time_total}\n" \
    https://www.example.com/problem-path
  sleep 2
done

如果每次失败都集中在同一个源站或同一个节点IP,问题就不再是“随机故障”。

多源站环境还要检查:

  • 各源站部署版本是否一致

  • 健康检查是否真正覆盖业务接口

  • 异常源站是否仍在负载均衡池中

  • 数据库和缓存配置是否一致

  • 某台服务器是否连接数耗尽

  • CDN是否仍在回源到已下线IP

日志应该按同一时间线对齐

有效的故障记录至少应该包含:

发生时间:精确到秒,并注明时区
访问域名和完整URL
请求方法
HTTP状态码
用户所在地区和运营商
CDN节点IP
源站IP
CDN请求ID
源站访问日志
源站错误日志
应用日志
请求总耗时

然后按相同时间点进行对照:

  1. CDN有记录,源站完全没有记录:问题可能发生在CDN到源站的连接阶段。

  2. 源站收到请求,但没有完成响应:检查应用阻塞、超时和进程异常。

  3. 源站明确返回503:检查容量、维护模式或应用限流。

  4. 源站返回200,用户却收到502:检查中间代理、响应格式和连接中断。

  5. CDN等待固定时长后返回504:检查回源超时阈值以及源站处理时间。

不要根据用户截图推测故障层级。只要能把CDN请求ID、源站访问日志和应用日志放到同一条时间线上,定位通常会快很多。

常见问题

CDN出现502,刷新后恢复,还需要处理吗?

需要。偶发502可能来自某台源站异常、应用进程重启、连接被重置或TLS握手失败。刷新恢复只说明下一次请求成功,不代表根因已经消失。

503是不是一定代表服务器过载?

不一定。503也可能来自维护模式、CDN限流、WAF规则、没有健康源站、应用未准备完成或套餐额度限制。先判断503是谁返回的,再检查资源使用率。

504是不是把CDN超时时间调大就能解决?

不一定。调大超时只能让CDN等待更久。如果根因是慢SQL、接口阻塞或外部服务异常,用户仍然需要等待很长时间,还会占用更多连接。

为什么静态文件正常,网站页面却504?

静态文件可能已经缓存在CDN节点,不需要回源;动态页面则需要访问源站、应用和数据库。静态资源正常不能证明源站动态服务正常。

为什么只有海外用户出现502或504?

可能与海外节点到源站的网络路径、防火墙策略、跨境链路或者区域回源配置有关。应该按国家、地区和节点IP记录结果,不要只在源站所在地区测试。

502、503、504会被CDN缓存吗?

取决于CDN厂商和缓存规则。有些配置会短暂缓存错误响应,也有些CDN会在源站故障时继续提供过期缓存。排查时应检查Age、缓存状态以及错误状态码缓存规则,不能默认每一次5xx都实时来自源站。

  • CDN 502
  • CDN 503
  • CDN 504
  • CDN回源失败
  • CDN回源超时
  • 网站502怎么办
  • 网站503错误
  • 504 Gateway Timeout