最近我的 WordPress 博客突然开始频繁出现 502 Bad Gateway。
最开始,我第一反应是服务器配置是不是已经不够用了。
毕竟目前这台阿里云 ECS 的配置并不高:
- 1 核 vCPU
- 2 GiB 内存
- 2 Mbps 固定公网带宽
- 20 GiB SSD 系统盘
- Alibaba Cloud Linux 3
- Nginx + PHP-FPM
- Redis 运行在 ECS 本机
- MySQL 使用阿里云 RDS,并不运行在这台 ECS 上
博客本身已经运行很多年,文章数量也越来越多。再加上最近一直在处理历史文章迁移、摘要生成、多语言翻译等工作,因此看到 502 后,我一度认为,可能终于到了需要把 ECS 从 1 核 2G 升级到 2 核 4G 的时候。
但后面的排查结果证明:
这次 502 的核心问题,并不是正常业务已经超出了 1 核 2G 的能力,而是一批异常高频、携带
Sogou web spiderUser-Agent 的访问,把 PHP-FPM 和 CPU 直接压到了极限。
而且整个故障从严重 502,到 EdgeOne 拦截后迅速恢复,过程非常典型。
一、故障现象:WordPress 后台开始间歇性 502
问题最明显的表现,是访问:
admin.shuijingwanwq.com/wp-admin/
时,开始间歇出现:
502 Bad Gateway
nginx

我尝试重启 ECS。
刚重启后网站会暂时恢复,但过一会儿又重新开始出现 502。
这就意味着问题不像单纯的某个服务偶发挂掉:
重启
→ 暂时正常
→ 负载重新上升
→ 再次 502
与此同时,阿里云 ECS 控制台已经记录到了大量 CPU 性能异常。
一天内出现了 30 次:
实例的 CPU 性能达到规格上限

这时已经可以确认:
服务器确实存在持续性的资源压力,而不是浏览器或者网络偶发错误。
二、一开始怀疑是不是清除服务器缓存导致的
问题出现前,我确实执行过一次服务器端缓存清理。
不过这里必须明确区分两层缓存。
我的网站架构大致是:
访客
↓
EdgeOne / Cloudflare
↓
Nginx
↓
W3 Total Cache / Redis
↓
PHP-FPM
↓
WordPress
↓
阿里云 RDS
我清除的是服务器上的 W3TC Page Cache、Object Cache 等缓存。
并没有清除 EdgeOne 和 Cloudflare 的 CDN 边缘缓存。
因此不能简单理解成:
清服务器缓存
→ CDN 全部 MISS
→ 所有用户突然回源
→ ECS 被打爆
这个因果关系是不成立的。
已有的 CDN HIT 仍然会继续由边缘节点直接返回。
服务器缓存被清空,只会增加那些原本就需要回源的请求的处理成本,比如:
- CDN 自然 MISS
- CDN TTL 到期后的首次回源
- WordPress 后台
- REST API
- WP-Cron
- 登录用户请求
- 动态请求
所以缓存清理可能是某个时间点上的影响因素,但不能直接解释持续一天的严重 502。
必须继续找真正的资源消耗者。
三、抓现场:Load 已经达到 9,CPU 完全没有空闲
重启服务器后大约 17 分钟,我开始直接检查系统状态。
结果非常夸张:
load average: 9.22, 9.55, 6.79
对于只有 1 核 CPU 的服务器来说,这个负载已经非常高。
继续看 vmstat:
us sy id wa
91 9 0 0
92 8 0 0
92 8 0 0
92 8 0 0
92 8 0 0
CPU idle 连续为:
0%
而且 iowait = 0。
也就是说:
CPU 不是在等待磁盘,也不是单纯卡在网络 I/O,而是真正在持续执行用户态程序。

四、真正吃满 CPU 的是 PHP-FPM
接下来检查 CPU 占用最高的进程。
结果非常整齐:
php-fpm 13.3%
php-fpm 13.3%
php-fpm 13.3%
php-fpm 13.3%
php-fpm 13.0%
php-fpm 12.9%
php-fpm 12.9%
总共 7 个 PHP-FPM Worker。
而 Redis 只有大约:
1.8%
Nginx 也只有:
0.9%
所以这次 ECS CPU 压力的主要来源已经很明确:
PHP-FPM。
与此同时,服务器上的 PHP-FPM 配置是:
pm.max_children = 7
pm.max_requests = 500
request_terminate_timeout = 600s
request_slowlog_timeout = 3s
也就是说,7 个 Worker 已经全部在高负载工作。
更严重的是 PHP-FPM Socket:
LISTEN 510 511 /dev/shm/php-cgi.sock
等待连接队列已经达到:
510 / 511
只差 1 个位置就完全塞满。
这已经足够解释为什么 Nginx 会返回 502:
Nginx
↓
PHP-FPM 7 个 Worker 全忙
↓
新的 PHP 请求不断进入
↓
FastCGI 队列持续积压
↓
510 / 511
↓
请求超时、失败
↓
502 / 499
五、不是内存问题,也不是 RDS 在本机吃 CPU
这次还有一个很容易误判的地方。
服务器只有 2 GiB 内存,但现场其实还有:
available ≈ 1.2 GiB
Swap 基本没有使用,也没有发现:
OOM
Out of memory
Killed process
所以这次不是典型的内存耗尽。
另外,我的 MySQL 使用的是阿里云 RDS,并没有运行在 ECS 本机。
因此不存在:
mysqld 90% CPU
这种情况。
服务器本地真正值得关注的是:
PHP-FPM
Redis
Nginx
而现场已经明确指向 PHP-FPM。
六、直接从 127.0.0.1 请求后台,照样大量 502
为了排除公网、DNS、EdgeOne、Cloudflare 等因素,我直接让 ECS 本机访问:
127.0.0.1
↓
Nginx
↓
PHP-FPM
↓
WordPress
连续测试 20 次。
结果非常惨。
有的请求:
HTTP=502
total≈0.1 秒
还有大量请求:
HTTP=000
15 秒超时
整个 20 次测试中,没有正常恢复。
这一步基本把外部网络因素排除了。
问题就在:
ECS
Nginx
PHP-FPM
WordPress
这一条内部链路里。
七、真正的突破口:最近 20,000 条请求中,18,455 条都是 Sogou UA
继续分析 Nginx 访问日志后,终于发现了真正异常的地方。
最近 20,000 条 www 请求,状态码统计为:
11925 499
7551 502
296 301
148 200
43 404
29 500
也就是说:
真正成功返回
200的请求,只剩 148 条。
大量请求已经变成 499 和 502。
但更加惊人的是 User-Agent:
18455 Sogou web spider/4.0
最近 20,000 条请求中,18,455 条都是:
Sogou web spider/4.0
占比超过:
92%
其他 Googlebot、Bingbot、Baiduspider、真实浏览器访问,与它相比几乎都只是零头。

八、每分钟 500~700 个请求,持续遍历大量不同页面
再按照分钟统计请求量:
14:01 546
14:02 623
14:04 724
14:05 678
14:09 595
14:13 638
14:14 609
14:22 592
14:25 604
14:29 572
长期维持在:
500~700 次/分钟
也就是大约:
8~12 次/秒
而且不是疯狂刷新同一个 URL。
它们在遍历:
文章页
分类页
分页
?p=xxxx
带 query 参数的页面
单个 URL 的请求量通常只有个位数或者十几次。
这意味着它更像是在:
高频遍历整个网站。
对于 CDN 来说,10 RPS 算不上什么巨大的攻击。
但对于:
1 核 CPU
+
WordPress 动态 PHP
+
每次执行可能达到 3 秒以上
+
pm.max_children = 7
却完全足够把源站压垮。
九、来源 IP 也非常分散
再看来源 IP:
117.40.82.101
117.40.82.170
125.94.249.28
1.71.146.14
222.79.117.159
222.79.116.117
1.71.147.232
1.71.147.97
125.94.249.39
122.246.2.213
……
很多 IP 单独就出现了接近 1,000 次请求。
这也意味着:
单纯按照某一个 IP 做限速或者封禁,效果可能并不好。
真正高度统一的是:
User-Agent: Sogou web spider/4.0
十、这些到底是不是真正的搜狗爬虫?
我其实很疑惑。
一个成熟的搜索引擎爬虫,在服务器已经持续返回大量 502 的情况下,理论上应该会降低抓取速度,而不是继续维持高频抓取。
所以我对这些请求是否真的来自 Sogou 产生了怀疑。
我抽取了 10 个最高频的来源 IP 做 PTR 反查:
117.40.82.101
117.40.82.170
125.94.249.28
1.71.146.14
222.79.117.159
222.79.116.117
1.71.147.232
1.71.147.97
125.94.249.39
122.246.2.213
结果全部是:
PTR: 无
因此这些 IP 无法通过 DNS 反向解析验证为真正的 Sogou Spider。
但这里我不会直接下结论说:
它们一定是假搜狗爬虫。
更严谨的描述应该是:
这是一批使用
Sogou web spider/4.0User-Agent,但无法验证为搜狗官方 Spider 的异常高频流量。
User-Agent 本身完全可以伪造。
所以目前最重要的不是追究它们到底是谁,而是先保护生产服务器。
十一、在 EdgeOne 直接屏蔽 *Sogou*
因为我的中文主站已经使用 EdgeOne,所以最有效的止血位置不是 Nginx,而是:
直接在 CDN 边缘节点拦截。
我在 EdgeOne:
安全防护
→ Web 防护
→ 自定义规则
→ 基础访问管控
创建:
规则名称:
屏蔽 Sogou 爬虫
匹配字段:
User-Agent
匹配方式:
通配符匹配
匹配内容:
*Sogou*
执行处置:
拦截

*Sogou* 拦截规则。规则发布后,在站点级防护策略中已经显示启用。

这里不需要清理 EdgeOne CDN 缓存。
安全规则和 CDN 内容缓存是两件不同的事情。
十二、屏蔽以后,服务器负载迅速开始下降
规则发布以后,大约几分钟时间,服务器状态就发生了非常明显的变化。
屏蔽前:
load average:
9.47, 9.63, 8.14
第一次复查:
3.11, 7.68, 8.58
再过几分钟:
2.69, 5.34, 7.31
随后:
1.81, 4.53, 6.88
1 分钟 Load 已经从接近 10 快速降到了不到 2。
由于 5 分钟和 15 分钟 Load 带有之前高负载时期的历史数据,所以下降速度会更慢,这是正常现象。
十三、Sogou 从 92% 直接降到 0
规则刚发布后的最近 200 条请求中:
Sogou = 16
已经从之前的 92% 下降到了很低的比例。
继续等待几分钟,再检查最近 100 条:
Sogou = 0
200 = 71
301 = 22
304 = 1
403 = 3
404 = 3
最关键的是:
502 = 0
499 = 0
正常 200 请求已经重新成为绝大多数。
这几乎是一次非常干净的 A/B 验证:
屏蔽前:
大量 Sogou UA
→ PHP-FPM 满载
→ 502
屏蔽后:
Sogou = 0
→ PHP-FPM 恢复
→ 502 = 0
十四、PHP-FPM 队列从 510/511 恢复到 0/511
这也是整个排查过程中最有说服力的指标之一。
故障高峰:
PHP-FPM Socket:
510 / 511
EdgeOne 拦截后:
PHP-FPM Socket:
0 / 511
积压请求彻底清空。
服务器内部访问 WordPress 后台,连续测试 5 次:
HTTP=200 0.110 秒
HTTP=200 0.341 秒
HTTP=200 0.321 秒
HTTP=200 0.469 秒
HTTP=200 0.247 秒
5 次全部成功。
再看实时 CPU:
CPU idle:
8%
90%
97%
最终已经达到:
97% 空闲
运行队列也从之前十几个等待任务,恢复到了:
r = 0
至此,这次生产故障基本可以确认已经恢复。

十五、这也改变了我对“是否升级 2C4G”的判断
在刚开始看到:
CPU 100%
Load 9+
PHP-FPM 堆积
大量 502
时,我确实很容易得出:
1 核 2G 已经不够用了。
如果没有继续查日志,我可能就会直接升级到 2 核 4G。
但现在结果已经证明:
异常流量停止
→ CPU idle 97%
说明:
正常状态下,这台 1 核 2G 服务器其实还有相当大的 CPU 余量。
因此我暂时不准备因为这次 502 就升级服务器。
2C4G 当然会带来更好的抗峰值能力。
但如果真正的问题是:
异常爬虫
→ 每分钟数百次动态请求
那么升级服务器只是:
从更早被打满
变成晚一点被打满
解决问题的优先级应该是:
先控制异常流量
↓
观察正常业务资源占用
↓
再决定是否真的需要升级
而不是遇到 502 就直接堆硬件。
十六、为什么暂时直接屏蔽 Sogou,而不是做复杂限速
这里其实还有一个取舍。
当前 EdgeOne 的规则:
*Sogou* → Block
意味着:
真正的搜狗爬虫也会被一起拦截。
这显然不是最精细的方案。
更理想的是:
正常、低频 Sogou
→ 放行
异常高频 Sogou
→ 限速或者拦截
但对我来说,目前 Sogou 本身有两个现实问题:
第一,我的网站在 Sogou 中索引量本来就很小。
第二,Sogou 几乎没有给我的博客带来什么有效流量。
而这次带着 Sogou UA 的异常请求,却已经真正导致:
CPU 100%
PHP-FPM 队列 510/511
后台 502
因此现阶段最合理的选择还是:
继续保留
*Sogou*拦截。
等网站稳定一段时间以后,如果确实还有必要保留搜狗 SEO,再研究 EdgeOne 的速率限制功能,把“一刀切 Block”升级为“超过阈值才拦截”。
但现在没有必要急着做。
十七、EdgeOne 的基础 Bot 管理暂时也解决不了这个问题
我后来还查看了当前个人版 EdgeOne 的 Bot 管理能力。
目前可以看到的主要功能包括:
人机校验页
AI 爬虫处置

但并没有看到可以直接:
识别真实 Sogou
→ 放行
伪造 Sogou UA
→ 拦截
这种精细化搜索引擎 Bot 策略。
因此现阶段还是使用:
User-Agent = *Sogou*
→ Block
最简单可靠。
十八、这次故障给我的几个经验
这次最大的收获,并不是“学会屏蔽一个 Sogou User-Agent”,而是重新确认了一套服务器故障排查顺序。
1. 502 不等于服务器配置一定不够
看到:
1C2G
CPU 100%
502
很容易第一时间想到:
升级服务器。
但这次真正的问题是异常流量。
如果不找到流量来源,升级只会掩盖问题。
2. Load、CPU 和 PHP-FPM 队列要结合看
这次真正把问题坐实的三个数据是:
Load ≈ 9
CPU idle = 0
PHP-FPM queue = 510 / 511
这比单独看某一个 CPU 百分比有意义得多。
3. 本机请求非常适合排除 CDN 和公网问题
使用:
127.0.0.1
直接请求 Nginx,可以迅速判断问题到底在:
外部网络 / CDN
还是:
ECS / Nginx / PHP-FPM / WordPress
这次本机一样大量 502,直接把排查范围缩小到了源站内部。
4. CDN 和服务器缓存必须严格区分
清 W3TC / Redis:
≠
清 EdgeOne / Cloudflare。
两层缓存不应该混为一谈。
5. User-Agent 不能证明爬虫身份
看到:
Sogou web spider/4.0
不能自动认为:
这一定是官方 Sogou Spider。
UA 可以随意伪造。
这次至少抽查的多个高频 IP 都无法通过 PTR 反查验证为 Sogou。
所以目前最严谨的称呼还是:
携带 Sogou UA 的异常高频流量。
十九、最终结果
这次故障最终没有:
- 升级 ECS
- 修改
pm.max_children - 重启 PHP-FPM
- 清理 CDN 缓存
- 调整 Redis
- 调整 RDS
- 给 Nginx 增加额外规则
真正执行的核心修复其实只有一个:
EdgeOne
→ User-Agent 通配符 *Sogou*
→ Block
然后:
Sogou UA
从 92%+
↓
0
服务器则从:
Load ≈ 9
CPU idle = 0%
PHP-FPM queue = 510 / 511
大量 499 / 502
恢复到:
Load 持续下降
CPU idle 最高 97%
PHP-FPM queue = 0 / 511
后台连续 5 次 HTTP 200
最近请求 502 = 0
整个过程也再次说明:
当服务器突然“性能不够”时,不要第一时间升级配置。
先回答一个问题:
到底是什么流量、什么进程、什么请求,把资源吃掉了?
有时候真正需要的不是更多 CPU,而是在离源站更远的地方,把本来就不应该进入 PHP 的请求挡掉。
这一次,EdgeOne 正好承担了这个角色。
Linux 服务器运维、部署与线上故障排查
如果你的网站或后端服务部署在 Linux 服务器上,遇到访问异常、Nginx 配置问题、MySQL / Redis 异常、Docker 服务不可用、磁盘占满、CPU / 内存过高等问题,可以联系我做一次远程排查。
适合以下场景:
✅ 网站打不开或访问不稳定
✅ Nginx / PHP-FPM 配置异常
✅ MySQL / Redis 性能或连接问题
✅ Docker 服务部署与维护
✅ 服务器迁移与环境配置
✅ CPU / 内存 / 磁盘异常排查
服务内容:
✅ Linux 环境检查
✅ 网站部署与迁移
✅ Nginx / PHP-FPM / MySQL / Redis 排查
✅ Docker 配置与维护
✅ 服务器性能分析
✅ 长期远程运维支持
如需咨询,请联系我,并注明:Linux 运维咨询。
联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com


发表回复