每天上午十点站点开始 502,数据库连接数卡在 151 的上限,慢查询里全是同一条 feed 查询,来源是几十个阅读器 IP。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

$key = 'feed:' . md5($_SERVER['REQUEST_URI']);
if ($cached = get_transient($key)) { echo $cached; exit; }
ob_start();
// 输出结束后 set_transient($key, ob_get_clean(), 300);

feed 每次请求都完整查一遍文章和元数据,没有缓存。多个阅读器按十分钟轮询,叠加起来就是每分钟两百次。连接池上限固定,查询一慢就连锁占满。这一点先确认清楚,后面就不用反复试。

「feed 请求打满数据库」这类改动最怕改一半,回滚脚本先准备好,再动生产。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

具体做法是,给 feed 输出加一层五分钟的缓存,命中时直接返回静态内容;限制同一 IP 的 feed 请求频率,超过就返回 429;把 feed 里的元数据查询合并,别再逐篇查一次自定义字段。

改完照着核一遍,并发请求下连接数保持在五十以内,feed 响应时间降到五十毫秒。

作者 9823189