今天上午,WordPress 所在的阿里云 ECS 再次出现了 CPU 异常。
这台服务器只有 2 vCPU,平时 CPU 使用率并不高。但这一次 CPU 很快升到接近 100%,而且不是持续几十秒的短暂尖峰,而是维持了相当长一段时间。系统平均负载也同步快速上升,一度达到 13~16 左右。
因为之前已经遇到过类似的高负载情况,所以这一次我首先想到的还是:
是不是又有异常流量突然打到了网站上?
继续查看 EdgeOne 后,很快就找到了一个非常明显的异常时间段。
一、CPU 接近 100%,系统负载同时飙升
从 ECS 监控可以看到,大约从 09:19 开始,CPU 使用率迅速升到接近 100%,并持续到 09:55 左右。
与此同时,系统平均负载也快速上升。
对于一台只有 2 vCPU 的服务器来说,十几的 Load 已经明显超出了正常范围。

内存使用率虽然有所波动,但并没有同步耗尽,因此当时首先需要确认的仍然是:
- 为什么 PHP / WordPress 突然有这么大的计算压力;
- 是正常流量增长,还是某种异常访问;
- EdgeOne 是否已经挡住或者缓存了其中一部分请求。
于是我开始查看 EdgeOne 的指标分析。
二、EdgeOne 在几分钟内出现明显的请求峰值
先把 EdgeOne 的时间范围设置为:
2026-09-01 09:10 ~ 10:00可以很明显地看到,在 09:16 之前访问量还比较正常,从 09:16 左右开始突然快速上升,在 09:20 左右达到峰值,随后又迅速下降。
整个时间范围内,L7 请求总量达到:
2.62 万次而且流量曲线与服务器 CPU 开始升高的时间基本对应。

这里已经足以说明:
这一次 CPU 告警和突然出现的大量访问之间,很可能存在明显关联。
不过 09:10~10:00 还是一个比较大的时间窗口,因此我继续把范围缩小到流量最集中的:
09:16 ~ 09:23三、7 分钟内出现约 2.35 万次请求
将时间缩小以后,可以看到:
09:16 ~ 09:23短短 7 分钟内,EdgeOne 统计到了大约:
2.35 万次 L7 请求缓存状态大致为:
miss 1.57 万次
hit 6632 次
other 1229 次
dynamic 3 次
一开始看到大量 miss 时,很容易直接理解成:
有一万多次请求直接进入了 PHP。
但实际上并不能这么简单计算。
我的网站架构大致是:
访客
↓
EdgeOne
↓
Nginx
↓
W3 Total Cache Disk Enhanced
↓
PHP-FPM / WordPress因此 EdgeOne 中的:
miss准确来说表示:
EdgeOne 节点没有直接命中 CDN 缓存,需要继续向源站请求。
但请求到达源站以后,还可能命中 W3 Total Cache 的页面缓存,并不代表每一次 EdgeOne miss 最终都执行了完整的 WordPress PHP 请求。
所以这张图能够证明的是:
大量请求需要回源。
但仅凭 EdgeOne 的 miss 数量,还不能直接计算到底有多少请求真正执行了 PHP。
这也是后面继续分析源站的原因之一。
四、异常请求并没有集中在少数几个 IP
如果是传统的单 IP 高频访问,最简单的办法通常是:
某个 IP 每分钟超过 N 次
→ 限速或者封禁但继续查看 EdgeOne 的客户端 IP 分布后,却发现这一次并不是这种情况。
在 09:16~09:23 的 TOP5 客户端 IP 中,最高的单个 IP 也只有:
24 次其他几个 TOP IP 分别也只有十几次。

这意味着总请求量虽然很大,但访问来源非常分散。
换句话说,如果只设置非常简单的:
单 IP 请求频率限制效果未必理想。
因为一个 IP 的请求量可能完全没有达到阈值,但成百上千个不同 IP 加起来,仍然足以给源站制造很大的压力。
这也是这次流量比较麻烦的地方。
五、请求 URL 同样非常分散
再查看 URL Path 分布,也可以看到类似的特点。
TOP URL 中既有:
/wp-content/plugins/...这样的资源路径,也有:
/category/...
/tag/...
/feed之类的 WordPress 页面。
没有出现某一个 URL 被持续几千、几万次集中请求的情况。

因此这一轮流量呈现出来的特点更接近:
大量不同 IP
+
大量不同 URL
+
短时间集中出现而不是:
少数 IP
+
少数固定 URL
+
持续高速请求这意味着单纯根据 IP 或单个 URL 做一个很死的限速规则,很容易出现两种结果:
要么设置得太宽松,挡不住这种分散流量;
要么设置得太严格,又容易误伤正常读者和搜索引擎爬虫。
六、源站日志中还出现了异常搜索请求
后续继续检查源站日志时,还发现了一些比较奇怪的 WordPress 搜索请求,例如:
?s=北化研究院+宋丹
?s='PL-I350-1G4
?s=EFEMERIDES+SEPTIEMBRE+PDF这些关键词彼此之间没有明显关联,也与我博客的主要技术内容没有多少关系。
单看一条搜索请求当然说明不了什么。
但结合前面的特征:
- 几分钟内突然产生两万多次请求;
- 来源 IP 高度分散;
- 请求 URL 高度分散;
- 搜索关键词也非常随机;
我更倾向于认为,这里面存在相当一部分自动化访问、爬虫或者搜索垃圾流量。
不过我没有把它简单定义成一次明确的“攻击”。
因为仅凭这些数据,还不足以精确判断所有请求的真实来源和目的。
对我来说更重要的是:
不管这些请求最终应该被归类成爬虫、扫描器还是其他自动化流量,它们已经实际导致了一台 2 vCPU 服务器接近满载,因此需要在 EdgeOne 层增加一些防护。
七、将 www 单独使用域名级防护策略
我的主站现在使用的是:
www.shuijingwanwq.com这次没有直接把整个 EdgeOne 站点的防护策略一起调高,而是让 www.shuijingwanwq.com 使用独立的域名防护策略。
原因也比较简单。
不同子域的业务性质并不完全一样。
如果因为主站遇到异常流量,就直接把所有域名都套上更严格的策略,可能会对其他业务产生没有必要的影响。
所以这一次调整的重点就是:
www.shuijingwanwq.com八、自适应频控调整为“适中”
EdgeOne 提供了自适应频控。
与自己固定设置:
每个 IP 每分钟最多 N 次相比,我更希望先让 EdgeOne 根据近期访问基线判断异常访问速度。
最终选择:
规则等级:自适应 - 适中处置方式使用:
JavaScript 挑战而不是直接封禁。
这样做主要还是为了降低误伤。
正常使用现代浏览器访问网站的读者,一般能够正常通过 JavaScript Challenge。
而一些简单的自动化脚本和爬虫,则可能因此增加访问成本或者直接无法继续请求。
九、同时开启流量防盗刷
除了自适应频控以外,我还开启了:
流量防盗刷(仅适用于中国大陆地区)处置方式同样选择:
JavaScript 挑战最终 www.shuijingwanwq.com 当前主要启用的两项规则就是:
自适应频控
规则等级:自适应 - 适中
处置方式:JavaScript 挑战
流量防盗刷
适用:中国大陆地区
处置方式:JavaScript 挑战
我暂时没有继续把规则调得更加激进。
毕竟这是一个公开博客。
Google、Bing、百度以及其他正常爬虫的访问,本身就是网站需要的。
如果因为一次异常流量就把所有自动访问都当成恶意请求处理,很可能会得不偿失。
十、个人版能力有限,只能在现有权限内尽量优化
这里还有一个现实限制需要说明。
我目前使用的是 EdgeOne 个人版本,因此并不是后台里所有安全防护能力都可以使用。
在这次排查过程中,其实有一些更适合针对异常流量做精细控制的配置项,但由于当前版本权限限制,我无法直接配置。
所以这次调整并不是:
已经选择了 EdgeOne 所能提供的最完整防护方案。
而更准确地说是:
在个人版本现有能力和权限范围内,尽量选择最适合当前流量特征、同时又不容易误伤正常访客的组合。
最终能够实际使用并且比较适合当前情况的主要就是:
www 使用独立域名防护策略
+
自适应频控:适中
+
JavaScript Challenge
+
中国大陆地区流量防盗刷这也是为什么我没有继续围绕固定 IP 阈值设计一大堆复杂规则。
一方面,这次异常流量本身就表现出了明显的分散特征:
IP 分散
+
URL 分散
+
单个 IP 请求量并不高另一方面,个人版本能够使用的安全能力也存在边界。
因此现阶段更实际的做法,是先充分利用现有版本提供的能力,把明显异常的自动化访问成本提高,同时尽量保证正常读者访问不受影响。
如果以后类似流量持续出现,而且个人版本提供的防护能力已经明显不足,再考虑是否有必要升级版本,或者从其他层面增加更精细的访问控制。
十一、为什么没有直接按 User-Agent 或 IP 封禁?
这次排查以后,我反而更加不倾向于依赖简单的固定规则。
例如按照浏览器 User-Agent:
Chrome
Edge直接判断是否异常,意义并不大。
自动化程序完全可以伪造正常浏览器 User-Agent。
同样,只依靠 IP 黑名单也很困难。
因为这次 TOP IP 的请求数甚至只有二十多次,而整体请求量却有两万多次。
也就是说:
单个 IP 看起来很正常并不意味着:
总体流量就是正常的对这种分布式、低单 IP 频率的自动化访问,自适应判断比单纯写一个固定阈值更适合当前情况。
十二、EdgeOne 的防护只能解决第一层问题
调整 EdgeOne 以后,CPU 最终恢复到了正常范围。
但这次排查没有在这里结束。
因为 EdgeOne 解决的是:
流量入口层也就是尽量减少不必要的异常请求继续打到源站。
但服务器为什么会在这些请求到来以后这么容易被拖到接近 100% CPU,还需要继续分析:
源站页面缓存是否正常?
PHP-FPM 在执行什么?
WordPress 是否还有其他异常?
W3 Total Cache 的缓存预热是否正常?继续往服务器里面查以后,我还真的发现了另外一个已经持续了半个月左右的问题:
W3 Total Cache 用于页面缓存预热的联合 Sitemap,竟然从 8 月 14 日以后就一直没有成功更新。
继续追下去又发现:
Yoast post-sitemap.xml
↓
HTTP 500
↓
PHP-FPM memory_limit 256M
↓
Allowed memory size exhausted这已经不是 EdgeOne 层面的问题了。
所以这一部分我准备单独放到下一篇继续记录。
十三、这次调整后的思路
这次最大的感受是,面对服务器突然满载,不能只看到一个现象就马上归因。
最开始看到:
CPU ≈ 100%很容易直接认为:
服务器性能不够。
看到 EdgeOne:
miss 1.57 万又容易直接认为:
一万多次请求全部执行了 PHP。
看到大量随机请求,又容易直接认为:
一定是某个 IP 在攻击。
但继续拆开以后,可以发现事情其实分成了几个不同的层次:
异常自动化流量
↓
EdgeOne 大量回源
↓
源站页面缓存
↓
PHP-FPM
↓
WordPress每一层都需要单独验证。
因此我现在采取的策略,并不是简单地把 EdgeOne 防护“拉到最高”。
一方面需要控制误伤,另一方面个人版本本身也存在功能和权限限制。
现阶段只能在已有能力范围内,尽量做出更适合当前流量特征的组合:
www 使用独立防护策略
+
自适应频控:适中
+
JavaScript Challenge
+
中国大陆流量防盗刷先降低明显异常流量对服务器的冲击,再继续处理源站本身的问题。
至于服务器内部到底又发现了什么,就留到下一篇继续整理。
WordPress 网站维护、性能优化与博客运营咨询
本站已持续运营超过 10 年,累计发布 1000+ 篇原创技术文章,长期实践 WordPress 网站建设、CDN / Cloudflare 配置、缓存优化、Google SEO、广告变现和多语言网站运营。
如果你的 WordPress 网站遇到访问慢、缓存异常、插件冲突、广告不显示、SEO 基础结构混乱、CDN 配置不确定等问题,可以联系我做一次远程技术排查。
适合以下用户:
✅ 个人博客站长
✅ WordPress 网站运营者
✅ 独立开发者与内容创作者
✅ SaaS 产品官网运营团队
✅ 希望优化网站速度与稳定性的站点
服务内容:
✅ WordPress 速度优化
✅ Cloudflare / CDN / 缓存配置排查
✅ 插件冲突与页面异常排查
✅ AdSense 广告显示问题排查
✅ SEO 基础结构检查
✅ 博客运营与商业化咨询
如需了解方案或交流相关问题,请直接联系我,并注明:WordPress 维护咨询。
联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

