惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
G
Google Developers Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
有赞技术团队
有赞技术团队
Vercel News
Vercel News
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
博客园_首页
The Cloudflare Blog
B
Blog
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
U
Unit 42
D
Docker
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
A
About on SuperTechFans

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次
Magento 服务器负载居高不下问题排除系列之二,屏蔽恶意爬虫
大象 · 2026-06-28 · via BlogFinder

之前整理了一期 Magento 服务器负载居高不下问题排除,没想到观察了几天发现服务器负载依然居高不下。

最终靠着 cloudflare 中设置访问规则,屏蔽了大量恶意爬虫,服务器负载终于恢复正常。

这里记录一下排除过程。特别是其中的 MySQL / MariaDB 相关的排查过程很有参考价值。

高负载依旧

在重建了 Magento 索引之后,没想到 MySQL 的 CPU 占用依旧很高,导致服务器负载居高不下。

排除交换分区的影响

我本以为是系统交换分区(swap)导致的高负载问题,查看了系统的 swap 使用情况,发现 swap 使用率很低,几乎没有使用到 swap 分区。

$ free -h
               total        used        free      shared  buff/cache   available
Mem:           7.7Gi       1.0Gi       6.5Gi       5.7Mi       363Mi       6.7Gi
Swap:          2.0Gi          0B       2.0Gi

以上是我本机的内存使用情况,并非服务器的,仅仅是为了说明 swap 使用率很低,几乎没有使用到 swap 分区。
这里的 available 内存是指系统可用的内存,free 内存是指系统空闲的内存,buff/cache 是指系统缓存的内存。总的来说,系统内存使用情况良好,没有出现内存不足的情况。

如果想看具体每个进程的 SWAP 分区使用情况,可以使用 smem 工具,安装方法如下:

sudo apt install smem

查看每个进程的 SWAP 分区使用情况:

$ sudo smem -t -k -s uss -r | head -25
  PID User     Command                         Swap      USS      PSS      RSS
  280 mysql    /usr/sbin/mysqld                   0   401.6M   403.6M   410.8M
  308 root     /usr/bin/dockerd -H fd:// -        0    78.8M    78.9M    81.9M
  211 root     /usr/bin/containerd                0    48.1M    48.1M    49.5M
  179 root     /usr/libexec/wsl-pro-servic        0    16.0M    16.0M    17.5M
  166 redis    /usr/bin/redis-server 127.0        0    13.0M    14.1M    20.3M
  164 root     php-fpm: master process (/e        0    11.2M    17.5M    34.2M

上面命令是查看 USS 占用排名前 25 的进程,USS 是指进程独占的内存大小,PSS 是指进程共享的内存大小,RSS 是指进程实际使用的物理内存大小。

show processlist 看不出问题

在 MySQL 中使用 show processlist 命令查看当前正在执行的 SQL 语句,发现没有明显的异常。
已经看不到满查询的情况了。之前没有建 magento 索引的时候,show processlist 中还会偶有慢查询,
但是现在已经没有了。大部分的 SQL 语句都是正常的查询语句,没有出现任何慢查询。

那为何从 top 命令看 MySQL 占用这么高的 CPU 呢?注意面试的时候,一定要说用了 top,否则一些脑残面试官,以为你啥也不知道。。。

查看 MySQL 每秒的 SQL 执行量

于是我怀疑是 MySQL 每秒的 SQL 执行量过高,导致 CPU 占用过高。

]> SHOW GLOBAL STATUS LIKE 'Questions';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| Questions     | 705205 |
+---------------+--------+
1 row in set (0.00 sec)

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'Questions';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| Questions     | 715310 |
+---------------+--------+
1 row in set (0.00 sec)

大概间隔了 5 秒钟左右,发现 Questions 的值增加了 10000 左右,说明 MySQL 每秒的 SQL 执行量大约是 2000 左右。
但是,这种纯手工计时的方式太不精确,于是改用 watch 命令来查看 MySQL 每秒的 SQL 执行量。

watch -n 10 'mysqladmin -uroot -ppassword status | grep Questions'

watch 命令每隔 10 秒钟执行一次 mysqladmin 命令,查看 MySQL 的状态信息,并过滤出 Questions 这一行。
同时计算出每秒的 SQL 执行量,发现 MySQL 每秒的 SQL 执行量大约是 1500 左右。🥲

这也太离谱了,MySQL 每秒的 SQL 执行量居然这么高,难怪 CPU 占用会这么高。

Nginx 日志定位到问题

因为之前看过 cloudflare 及 Nginx 的访问日志,从日志看,请求量也就在每秒 20 次左右。
这个访问量很小,我一直没有当回事。确实是我大意了。

再次仔细看了一下 Nginx 日志,发现这每秒 20 次的请求,实际应该是同一来源。因为 User Agent 类似。

而且都是访问的 Magento 的产品列表页的属性过滤功能,但是属性参数每次都不一样。

这个网站 170 万多个产品,100 多属性,属性组合非常多,导致恶意爬虫在抓取产品列表页的时候,访问了大量的不同属性组合的 URL。
我怀疑是这个属性列表页的属性组合导致了 MySQL 每秒的 SQL 执行量过高,最终导致 MySQL CPU 占用过高。

而这个我又没法做本地缓存,因为磁盘空间不太够。

通过 cloudflare 屏蔽恶意爬虫

所以,先临时启用了 cloudflare 的访问规则,除了认证的正规爬虫(如 Googlebot、Bingbot 等)之外,其他的所有请求都开启人类验证(Challenge)模式。

但是,需要排除首页,毕竟需要防止宕机监控请求也被挑战。

尝试了一下只部分属性列表路径才开启挑战,但是发现相关的页面规则太多,最终还是选择了对所有路径开启挑战模式。

暂时看是正常了。系统负载也恢复正常了。

待续

  • 为何属性组合会导致 MySQL 每秒的 SQL 执行量过高?
  • 为何屏蔽了恶意爬虫之后,MySQL 的 CPU 占用没有立即下降?而且在重启 MySQL 之后,CPU 占用才正常?是因为数据库的 SQL 队列机制,还是 PHP 的请求队列机制?还是其他原因?

关于作者 🌱

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式