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-pathcurl -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: 504DNS、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
源站访问日志
源站错误日志
应用日志
请求总耗时然后按相同时间点进行对照:
CDN有记录,源站完全没有记录:问题可能发生在CDN到源站的连接阶段。
源站收到请求,但没有完成响应:检查应用阻塞、超时和进程异常。
源站明确返回503:检查容量、维护模式或应用限流。
源站返回200,用户却收到502:检查中间代理、响应格式和连接中断。
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