站内搜索走 /api/search?kw=,没有鉴权也没限频。日志里同一个 IP 一天请求 20 万次,把搜索词组合全跑了一遍,服务器负载从 0.8 涨到 12,正常页面的 TTFB 跟着变慢。

原因不止一个,得分开看。接口对匿名请求完全开放,没有频率限制;结果页允许被外链直接引用,被当成免费查询服务;日志里大量请求来自同一段云主机地址;缓存只按关键词命中,随机词全部穿透到数据库。

上来先按 IP 统计请求量找出主要来源

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

然后在 Nginx 层按 IP 限速

limit_req_zone $binary_remote_addr zone=search:10m rate=2r/s;

接着验证外站 Referer 请求是否被放行

curl -s -o /dev/null -w '%{http_code}\n' -H 'Referer: https://other.site/' 'https://www.example.com/api/search?kw=nginx'

给高频关键词加短时缓存

proxy_cache_valid 200 5m;

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

别只看报错消失,验证要多做一步。单 IP 每分钟请求降到 120 次以内,负载回落到 1 以下,页面 TTFB 恢复到 200ms 左右。

搜索接口是最容易被刷的入口,限频放在最外层,比在应用里判断更早生效。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189