内容提要
博客因被异常抓取导致带宽占满而变慢。分析27天日志发现75个IP高频请求,占全站42%,读取文章库1418次。作者弃用IP封禁,改用Caddy限流:全部请求120次/分钟、页面请求60次/分钟。上线后异常HTML请求降84.5%,响应流量降79.9%,新增1287次429拦截,正常访问未受影响。
延伸解读
限流阈值如何定?回放日志是关键
作者没有拍脑袋定阈值,而是用最近24小时日志做固定自然分钟回放,对比不同阈值命中异常IP的情况,最终选定全部请求120次/分钟、页面请求60次/分钟。这说明限流参数需要基于自身流量特征调整,照搬他人数值可能误伤或失效。上线后仍需根据429和误伤情况持续调整。
IP封禁为何不如限流?
异常IP在27天内换了75个,且单个IP活跃期短,封禁只能短期止血,批量封禁易误伤正常用户。限流按IP控制请求频率,不关心请求来源,既能拦截高频抓取,又对正常访问影响小。这提示应对分布式爬虫时,频率限制比黑名单更可持续。
限流效果显著,但需警惕误伤
上线后同一时段,异常IP成功获取HTML减少84.5%,响应流量下降79.9%,新增1287次429拦截,正常访问未受影响。但单小时数据不能代表长期效果,且429中可能混有搜索引擎等合法爬虫,需持续观察日志,避免误伤。
Q&A
我的博客为什么突然变慢了?
因为博客被大量异常请求刷带宽,公网出口带宽被占满,导致正常读者加载图片等资源变慢。
如何识别博客被异常抓取?
通过分析访问日志,发现异常请求具有以下特征:大量IP(75个)高频请求,单个IP活跃时间短且频繁更换;User-Agent频繁变化(45种Chrome版本);请求目标主要是RSS和文章HTML,几乎不加载图片;请求频率极高,如最高一分钟627次,且连续突发请求间隔极短。
为什么不用IP封禁来应对异常抓取?
因为异常IP数量多(75个)且频繁更换,封禁只能短期止血,且容易误伤正常用户,所以作者选择改用请求频率限流。
如何设置Caddy限流阈值?
作者通过回放最近24小时日志,测试不同阈值,最终设置两个限流区:全部请求120次/分钟/IP,页面请求60次/分钟/IP。页面请求包括HTML、分类、标签和RSS,其他资源只受120次/分钟限制。
如何在Caddy中启用限流功能?
Caddy官方二进制不包含rate_limit,需要使用xcaddy构建自定义版本,并添加mholt/caddy-ratelimit模块。构建后,在Caddyfile中配置rate_limit指令,定义两个zone(blog_all和blog_pages),然后校验配置并重启Caddy服务。
限流上线后效果如何?
限流上线后,异常IP成功获取的HTML减少了84.5%,响应流量减少了79.9%,新增1287次429拦截,全站请求量下降53.7%,正常访问未受影响。
限流阈值是通用的吗?
不是,120次/分钟和60次/分钟只是作者根据日志回放选出的起点,后续需要根据429和误伤情况调整。