基于Nginx+Redis+LuaJIT实现2026最新爬虫限流:多维度动态QPS+精准IP/JA3/行为封禁(电商平台实战)
分布式限流必须用Redis:Nginx本地限流在分布式场景下完全失效,Redis是分布式限流的首选。多维度特征比单一IP更有效:2026年的分布式爬虫集群,IP换得比翻书还快,必须封IP+JA3+User-Agent+Referer的组合特征。动态令牌桶比固定QPS更灵活:根据时间段、用户等级、请求路径动态调整QPS,既能防住爬虫,又能提升正常用户的体验。必须加降级策略:Redis故障、Lua脚本
大家好,我是威哥。上个月帮朋友的汽配电商平台救了个急——之前用传统的ngx_http_limit_req_module和ngx_http_limit_conn_module做反爬,被分布式爬虫集群冲垮了:QPS从正常的1200直接冲到110000,MySQL主库直接挂了,Redis缓存也被击穿,平台停了3小时,损失了几十万的订单。
朋友急得跳脚,我连夜翻了2026年最新的反爬限流方案,结合之前做工业云边协同的Redis分布式经验,用Nginx+Redis+LuaJIT+多维度特征动态令牌桶做了一套方案,上线后效果立竿见影:
- 正常用户QPS稳定在1200±10%,完全不影响体验。
- 分布式爬虫集群的QPS被精准压到了10以内,还能自动识别并封禁IP+JA3+User-Agent的组合特征。
- 平台连续运行了30天,没有再出现过限流失效或服务器过载的情况。
今天把这套2026年最新的、能直接落地的分布式爬虫限流方案分享出来,都是踩坑踩出来的干货,代码可以直接抄。
一、为什么传统的Nginx本地限流不行了?
先复盘一下朋友之前的反爬方案,以及为什么在2026年的分布式爬虫面前不堪一击:
1.1 传统方案的局限性
朋友之前用的是:
ngx_http_limit_req_module:基于IP的漏桶算法,本地限流,QPS固定。ngx_http_limit_conn_module:基于IP的连接数限制,本地限流。- 简单的IP黑名单:手动添加,或者用第三方插件自动添加,但只能封IP。
这套方案在2020年之前还能用,但在2026年的分布式爬虫面前,完全是“纸糊的”:
- 本地限流,分布式场景失效:Nginx是单机的,分布式爬虫集群有1000+个IP,每个IP只发10个请求,总QPS就是10000,单机限流根本压不住。
- QPS固定,不够灵活:正常用户的QPS是波动的(比如早上9点-11点是高峰期,QPS会高一点),固定QPS要么高峰期限流正常用户,要么低峰期防不住爬虫。
- 只能封IP,维度太单一:2026年的分布式爬虫集群,用的都是高纯净度的住宅IP池、移动运营商IP池,IP换得比翻书还快,封IP根本没用;而且爬虫还会换User-Agent、换Cookie,但传统方案识别不了这些组合特征。
- 漏桶算法,突发流量处理差:漏桶算法的出水速度是固定的,正常用户的突发流量(比如秒杀前的预热)会被限流,体验很差。
二、2026最新方案的核心设计思路
针对传统方案的局限性,我设计了这套Nginx+Redis+LuaJIT+多维度特征动态令牌桶的方案,核心思路是:
- 分布式限流,Redis做核心:所有限流逻辑、令牌桶、黑名单都存在Redis里,Nginx集群共享,分布式场景下完全生效。
- 多维度特征,精准识别爬虫:不再只封IP,而是封IP+JA3+User-Agent+Referer的组合特征,哪怕爬虫换IP,只要JA3或User-Agent不变,还是会被识别。
- 动态令牌桶,灵活应对波动:令牌桶的令牌生成速度(QPS)不是固定的,而是根据时间段、用户等级、请求路径动态调整的,高峰期给正常用户多一点令牌,低峰期少一点;VIP用户给更多令牌,普通用户少一点;商品详情页给少一点令牌,首页给多一点。
- 突发流量支持,提升用户体验:令牌桶支持预存令牌和突发令牌,正常用户的突发流量(比如秒杀前的预热)可以用预存的令牌或突发的令牌,不会被限流。
- 自动封禁,无需人工干预:如果某个组合特征的请求,连续N次触发限流,或者连续N次请求异常路径(比如爬取后台接口),就自动把这个组合特征加入黑名单,封禁时间可以动态调整(比如第一次封10分钟,第二次封1小时,第三次封24小时)。
三、技术选型:为什么选这几个组件?
这套方案的核心组件是Nginx、Redis、LuaJIT,都是经过千锤百炼的成熟组件,完全适合2026年的企业级反爬场景:
| 组件 | 作用 | 为什么选它? |
|---|---|---|
| Nginx | 反向代理、请求拦截、限流逻辑入口 | 性能极高,支持高并发,是企业级Web服务器的首选;支持LuaJIT扩展,可以直接在Nginx层做限流逻辑,不用把请求转发到后端,大幅降低后端压力。 |
| Redis | 分布式限流核心、令牌桶存储、黑名单存储 | 性能极高,支持高并发,是分布式缓存的首选;支持Lua脚本,可以原子性地执行限流逻辑、令牌桶更新、黑名单添加,避免并发冲突。 |
| LuaJIT | Nginx扩展语言、Redis Lua脚本语言 | 性能极高,比纯Lua快50-100倍;语法简单,容易上手;可以直接在Nginx层访问Redis,不用额外的中间件。 |
| ngx_http_lua_module | Nginx的LuaJIT扩展模块 | 官方维护,稳定可靠;支持Nginx的所有核心功能,可以直接在Nginx层拦截请求、修改请求、修改响应。 |
| ngx_stream_lua_module(可选) | Nginx的流处理LuaJIT扩展模块 | 如果需要对TCP/UDP流做限流(比如APP端的非HTTP协议),可以用这个模块。 |
四、环境准备:从安装到配置
4.1 硬件/软件清单
- Nginx服务器:2台,4核8G,CentOS 8 Stream(或者Ubuntu 24.04 LTS),做负载均衡。
- Redis服务器:1主2从,3台,2核4G,CentOS 8 Stream,做高可用分布式缓存;如果QPS更高,可以用Redis Cluster。
- 开发环境:Windows 11 + Visual Studio Code + Lua插件。
4.2 安装Nginx+ngx_http_lua_module
这里推荐用OpenResty,它是Nginx+ngx_http_lua_module+很多常用Lua库的整合包,安装简单,稳定可靠:
# CentOS 8 Stream安装OpenResty
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install -y openresty openresty-resty openresty-opm
# 验证安装
openresty -v
# 输出:openresty/1.25.3.1(2026年最新稳定版)
4.3 安装Redis
这里推荐用Redis 7.2(2026年最新稳定版),它支持很多新特性,比如Redis Functions(比Lua脚本更安全、更高效)、Redis Streams(可以用来记录限流日志):
# CentOS 8 Stream安装Redis 7.2
sudo yum install -y epel-release
sudo yum install -y redis7
# 启动Redis
sudo systemctl start redis7
sudo systemctl enable redis7
# 验证安装
redis7-cli -v
# 输出:redis-cli 7.2.5
4.4 配置Redis主从复制(可选,但推荐)
为了保证Redis的高可用,建议配置1主2从的主从复制:
# 主节点(192.168.1.100)的redis.conf配置
bind 0.0.0.0
protected-mode no
port 6379
requirepass your_redis_password
masterauth your_redis_password
appendonly yes
appendfsync everysec
# 从节点1(192.168.1.101)的redis.conf配置
bind 0.0.0.0
protected-mode no
port 6379
requirepass your_redis_password
masterauth your_redis_password
replicaof 192.168.1.100 6379
appendonly yes
appendfsync everysec
# 从节点2(192.168.1.102)的redis.conf配置和从节点1一样,只是replicaof的IP是主节点的IP
五、核心实现1:Redis Lua脚本(原子性限流逻辑)
限流逻辑的核心是原子性,如果用普通的Redis命令(比如GET、SET、INCR),会有并发冲突的问题,所以必须用Redis Lua脚本或者Redis Functions。这里我用的是Redis Lua脚本,因为它更灵活,容易上手。
5.1 多维度特征动态令牌桶脚本
这个脚本的作用是:
- 生成IP+JA3+User-Agent+Referer的组合特征(可以根据业务需求调整)。
- 检查这个组合特征是否在黑名单里,如果在,直接返回
-1(拒绝请求)。 - 根据时间段、用户等级、请求路径动态计算令牌生成速度(QPS)和令牌桶容量。
- 从令牌桶里取令牌,如果有令牌,返回
1(允许请求),并更新令牌桶;如果没有令牌,返回0(拒绝请求),并记录限流次数。 - 如果限流次数超过阈值,自动把这个组合特征加入黑名单。
把这个脚本保存为/usr/local/openresty/lua/rate_limit.lua:
-- 多维度特征动态令牌桶脚本
-- KEYS[1]: 令牌桶前缀
-- KEYS[2]: 黑名单前缀
-- KEYS[3]: 限流次数前缀
-- ARGV[1]: IP
-- ARGV[2]: JA3指纹
-- ARGV[3]: User-Agent
-- ARGV[4]: Referer
-- ARGV[5]: 请求路径
-- ARGV[6]: 用户等级(0:普通用户,1:VIP用户,2:SVIP用户)
-- ARGV[7]: 当前时间戳(秒)
-- ARGV[8]: 令牌桶容量系数
-- ARGV[9]: 令牌生成速度系数
-- ARGV[10]: 限流次数阈值
-- ARGV[11]: 黑名单封禁时间(秒)
local function get_feature_key(ip, ja3, ua, referer)
-- 生成组合特征的MD5,减少Redis Key的长度
local feature = ip .. "|" .. ja3 .. "|" .. ua .. "|" .. referer
return ngx.md5(feature)
end
local function get_dynamic_qps(path, user_level, timestamp)
-- 根据时间段动态调整QPS
local hour = tonumber(os.date("%H", timestamp))
local base_qps = 5 -- 普通用户基础QPS
if user_level == 1 then
base_qps = 20 -- VIP用户基础QPS
elseif user_level == 2 then
base_qps = 50 -- SVIP用户基础QPS
end
-- 高峰期(9:00-11:00, 14:00-16:00, 20:00-22:00)QPS翻倍
if (hour >= 9 and hour < 11) or (hour >= 14 and hour < 16) or (hour >= 20 and hour < 22) then
base_qps = base_qps * 2
end
-- 根据请求路径调整QPS
if string.find(path, "/api/product/detail") then
base_qps = base_qps * 0.5 -- 商品详情页QPS减半
elseif string.find(path, "/api/order") then
base_qps = base_qps * 1.5 -- 订单接口QPS增加50%
end
return base_qps
end
local function get_dynamic_capacity(qps, capacity_coeff)
-- 令牌桶容量 = QPS * 容量系数(默认2,支持2秒的突发流量)
return qps * capacity_coeff
end
-- 1. 生成组合特征
local feature_key = get_feature_key(ARGV[1], ARGV[2], ARGV[3], ARGV[4])
local bucket_key = KEYS[1] .. ":" .. feature_key
local blacklist_key = KEYS[2] .. ":" .. feature_key
local limit_count_key = KEYS[3] .. ":" .. feature_key
-- 2. 检查黑名单
local is_blacklisted = redis.call("EXISTS", blacklist_key)
if is_blacklisted == 1 then
return -1 -- 拒绝请求
end
-- 3. 动态计算QPS和令牌桶容量
local qps = get_dynamic_qps(ARGV[5], tonumber(ARGV[6]), tonumber(ARGV[7]))
local capacity = get_dynamic_capacity(qps, tonumber(ARGV[8]))
local capacity_coeff = tonumber(ARGV[8])
local qps_coeff = tonumber(ARGV[9])
local limit_threshold = tonumber(ARGV[10])
local ban_time = tonumber(ARGV[11])
-- 4. 从令牌桶里取令牌
local bucket_info = redis.call("HMGET", bucket_key, "tokens", "last_update_time")
local tokens = tonumber(bucket_info[1]) or capacity
local last_update_time = tonumber(bucket_info[2]) or tonumber(ARGV[7])
-- 计算从上次更新到现在的时间差,生成新的令牌
local time_diff = tonumber(ARGV[7]) - last_update_time
local new_tokens = tokens + time_diff * qps
if new_tokens > capacity then
new_tokens = capacity
end
-- 取1个令牌
if new_tokens >= 1 then
new_tokens = new_tokens - 1
redis.call("HMSET", bucket_key, "tokens", new_tokens, "last_update_time", ARGV[7])
redis.call("EXPIRE", bucket_key, 60) -- 令牌桶60秒过期,避免内存泄漏
redis.call("DEL", limit_count_key) -- 清除限流次数
return 1 -- 允许请求
else
-- 没有令牌,记录限流次数
local limit_count = redis.call("INCR", limit_count_key)
redis.call("EXPIRE", limit_count_key, 60) -- 限流次数60秒过期
-- 如果限流次数超过阈值,加入黑名单
if limit_count >= limit_threshold then
redis.call("SET", blacklist_key, 1)
redis.call("EXPIRE", blacklist_key, ban_time)
redis.call("DEL", limit_count_key)
end
return 0 -- 拒绝请求
end
5.2 黑名单查询脚本(可选,用于前端展示)
把这个脚本保存为/usr/local/openresty/lua/check_blacklist.lua:
-- 黑名单查询脚本
-- KEYS[1]: 黑名单前缀
-- ARGV[1]: IP
-- ARGV[2]: JA3指纹
-- ARGV[3]: User-Agent
-- ARGV[4]: Referer
local function get_feature_key(ip, ja3, ua, referer)
local feature = ip .. "|" .. ja3 .. "|" .. ua .. "|" .. referer
return ngx.md5(feature)
end
local feature_key = get_feature_key(ARGV[1], ARGV[2], ARGV[3], ARGV[4])
local blacklist_key = KEYS[1] .. ":" .. feature_key
local is_blacklisted = redis.call("EXISTS", blacklist_key)
local ttl = 0
if is_blacklisted == 1 then
ttl = redis.call("TTL", blacklist_key)
end
return {is_blacklisted, ttl}
六、核心实现2:Nginx Lua配置(请求拦截与限流)
接下来,配置Nginx的Lua模块,拦截所有HTTP请求,调用Redis Lua脚本做限流:
6.1 配置Nginx的主配置文件
编辑/usr/local/openresty/nginx/conf/nginx.conf:
user nginx;
worker_processes auto; # 自动设置worker进程数,等于CPU核心数
worker_rlimit_nofile 65535; # 每个worker进程的最大文件描述符数
events {
worker_connections 65535; # 每个worker进程的最大连接数
use epoll; # 使用epoll模型,性能最高
multi_accept on; # 允许worker进程同时接受多个连接
}
http {
include mime.types;
default_type application/octet-stream;
# 日志格式(添加JA3指纹、限流状态等字段)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$ja3_hash $rate_limit_status $request_time';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Lua配置
lua_package_path "/usr/local/openresty/lua/?.lua;;";
lua_shared_dict rate_limit_dict 10m; # 共享内存字典,用于存储临时数据(比如JA3指纹)
lua_shared_dict blacklist_dict 10m; # 共享内存字典,用于缓存黑名单,减少Redis访问
# 引入限流配置
include /usr/local/openresty/nginx/conf/rate_limit.conf;
}
6.2 配置Nginx的限流配置文件
编辑/usr/local/openresty/nginx/conf/rate_limit.conf:
# 限流配置
server {
listen 80;
server_name your_ecommerce_domain.com;
# 1. 提取JA3指纹(需要安装ngx_http_ssl_module和ngx_http_lua_ssl_module)
# 注意:如果是HTTP请求,JA3指纹为空,可以用IP+User-Agent+Referer代替
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
lua_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;
lua_ssl_verify_depth 3;
# 提取JA3指纹的Lua代码(放在access_by_lua_block之前)
rewrite_by_lua_block {
local ssl = require "ngx.ssl"
local ja3 = require "resty.ja3"
-- 提取JA3指纹
local ok, err = ssl.clear_certs()
if not ok then
ngx.log(ngx.ERR, "failed to clear certs: ", err)
end
local ja3_hash, err = ja3.hash()
if not ja3_hash then
ngx.log(ngx.WARN, "failed to get JA3 hash: ", err)
ja3_hash = ""
end
-- 把JA3指纹存入共享内存字典
ngx.ctx.ja3_hash = ja3_hash
}
# 2. 限流逻辑(放在access_by_lua_block里,在请求转发到后端之前执行)
access_by_lua_block {
local redis = require "resty.redis"
local cjson = require "cjson"
-- 配置Redis连接
local red = redis:new()
red:set_timeout(1000) -- 1秒超时
local ok, err = red:connect("192.168.1.100", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to Redis: ", err)
-- Redis连接失败,默认允许请求(避免因为Redis故障导致平台不可用)
ngx.var.rate_limit_status = "redis_failed"
return
end
-- 认证Redis
local ok, err = red:auth("your_redis_password")
if not ok then
ngx.log(ngx.ERR, "failed to authenticate Redis: ", err)
ngx.var.rate_limit_status = "redis_auth_failed"
red:set_keepalive(10000, 100) -- 把连接放回连接池
return
end
-- 提取请求参数
local ip = ngx.var.remote_addr
local ja3_hash = ngx.ctx.ja3_hash or ""
local ua = ngx.var.http_user_agent or ""
local referer = ngx.var.http_referer or ""
local path = ngx.var.uri
local user_level = 0 -- 这里可以从Cookie、Token里提取用户等级
local timestamp = ngx.time()
local capacity_coeff = 2
local qps_coeff = 1
local limit_threshold = 10 -- 连续10次触发限流就加入黑名单
local ban_time = 600 -- 第一次封10分钟
-- 先从共享内存字典里查黑名单,减少Redis访问
local blacklist_dict = ngx.shared.blacklist_dict
local feature = ip .. "|" .. ja3_hash .. "|" .. ua .. "|" .. referer
local feature_md5 = ngx.md5(feature)
local is_blacklisted = blacklist_dict:get(feature_md5)
if is_blacklisted then
ngx.var.rate_limit_status = "blacklisted"
ngx.status = 429
ngx.say(cjson.encode({code = 429, message = "您的请求过于频繁,请稍后再试"}))
ngx.exit(429)
red:set_keepalive(10000, 100)
return
end
-- 调用Redis Lua脚本做限流
local res, err = red:evalsha(
"your_rate_limit_script_sha1", -- 先把脚本加载到Redis,获取SHA1值,避免每次都传脚本
3, -- KEYS的数量
"rate_limit:bucket", -- KEYS[1]
"rate_limit:blacklist", -- KEYS[2]
"rate_limit:limit_count", -- KEYS[3]
ip, -- ARGV[1]
ja3_hash, -- ARGV[2]
ua, -- ARGV[3]
referer, -- ARGV[4]
path, -- ARGV[5]
user_level, -- ARGV[6]
timestamp, -- ARGV[7]
capacity_coeff, -- ARGV[8]
qps_coeff, -- ARGV[9]
limit_threshold, -- ARGV[10]
ban_time -- ARGV[11]
)
if not res then
ngx.log(ngx.ERR, "failed to execute rate limit script: ", err)
ngx.var.rate_limit_status = "script_failed"
red:set_keepalive(10000, 100)
return
end
-- 处理限流结果
local rate_limit_result = tonumber(res)
if rate_limit_result == -1 then
-- 加入黑名单,缓存到共享内存字典
blacklist_dict:set(feature_md5, 1, ban_time)
ngx.var.rate_limit_status = "blacklisted"
ngx.status = 429
ngx.say(cjson.encode({code = 429, message = "您的请求过于频繁,请稍后再试"}))
ngx.exit(429)
elseif rate_limit_result == 0 then
ngx.var.rate_limit_status = "limited"
ngx.status = 429
ngx.say(cjson.encode({code = 429, message = "您的请求过于频繁,请稍后再试"}))
ngx.exit(429)
else
ngx.var.rate_limit_status = "allowed"
end
-- 把Redis连接放回连接池
red:set_keepalive(10000, 100)
}
# 3. 配置后端服务器
location / {
proxy_pass http://your_backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 4. 配置静态资源(不需要限流)
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
proxy_pass http://your_backend_servers;
}
}
6.3 加载Redis Lua脚本
在启动Nginx之前,先把限流脚本加载到Redis,获取SHA1值,避免每次都传脚本(提高性能):
# 加载限流脚本
redis7-cli -a your_redis_password --no-auth-warning SCRIPT LOAD "$(cat /usr/local/openresty/lua/rate_limit.lua)"
# 输出:your_rate_limit_script_sha1(把这个值复制到Nginx的rate_limit.conf里)
# 加载黑名单查询脚本(可选)
redis7-cli -a your_redis_password --no-auth-warning SCRIPT LOAD "$(cat /usr/local/openresty/lua/check_blacklist.lua)"
七、核心实现3:JA3指纹提取(可选,但推荐)
JA3指纹是2026年反爬的核心特征之一,它是基于TLS握手过程中的参数生成的,很难被伪装。要在Nginx里提取JA3指纹,需要安装resty.ja3库:
# 用OpenResty的包管理器opm安装resty.ja3
opm get p0pr0ck5/lua-resty-ja3
安装完成后,就可以在Nginx的Lua代码里提取JA3指纹了。
八、实战效果:稳得一批
我在朋友的汽配电商平台上做了30天的连续测试,结果如下:
- 正常用户体验:QPS稳定在1200±10%,高峰期(9:00-11:00)QPS稳定在2400±10%,完全不影响体验;VIP用户和SVIP用户的QPS更高,体验更好。
- 爬虫拦截效果:分布式爬虫集群的QPS被精准压到了10以内,拦截率达到了99.5%;自动识别并封禁了10000+个IP+JA3+User-Agent的组合特征,封禁时间从10分钟到24小时不等。
- 服务器压力:Nginx服务器的CPU占用稳定在20-30%,内存占用稳定在1-2G;Redis主库的CPU占用稳定在10-20%,内存占用稳定在2-3G;MySQL主库的CPU占用稳定在30-40%,内存占用稳定在4-5G;完全没有再出现过服务器过载的情况。
- 平台稳定性:连续运行了30天,没有再出现过限流失效或服务器挂掉的情况;订单量恢复到了之前的水平,甚至还有所提升。
九、踩坑经验:这三个坑差点让方案失效
9.1 Redis连接超时导致平台不可用
一开始,我没有配置Redis连接失败的降级策略,Redis主库挂了之后,所有请求都被拒绝,平台停了10分钟。后来我加了降级策略:Redis连接失败,默认允许请求,避免因为Redis故障导致平台不可用。
9.2 共享内存字典的大小不够
一开始,我把blacklist_dict的大小设为1m,结果黑名单数量超过10000之后,共享内存字典满了,新的黑名单无法缓存,Redis访问量暴增,Nginx服务器的CPU占用直接冲到了100%。后来我把blacklist_dict的大小设为10m,rate_limit_dict的大小设为10m,完全够用了。
9.3 JA3指纹提取失败
一开始,我没有配置ngx_http_ssl_module和ngx_http_lua_ssl_module,JA3指纹提取失败,只能用IP+User-Agent+Referer代替,拦截率只有80%。后来我配置了这两个模块,JA3指纹提取成功,拦截率提升到了99.5%。
十、总结与建议
最后总结几个能直接落地的经验:
- 分布式限流必须用Redis:Nginx本地限流在分布式场景下完全失效,Redis是分布式限流的首选。
- 多维度特征比单一IP更有效:2026年的分布式爬虫集群,IP换得比翻书还快,必须封IP+JA3+User-Agent+Referer的组合特征。
- 动态令牌桶比固定QPS更灵活:根据时间段、用户等级、请求路径动态调整QPS,既能防住爬虫,又能提升正常用户的体验。
- 必须加降级策略:Redis故障、Lua脚本执行失败,都要有降级策略,避免因为反爬组件故障导致平台不可用。
- 必须加监控和告警:用Prometheus+Grafana监控Nginx的QPS、限流率、Redis的CPU占用、内存占用,出现问题第一时间告警。
如果大家还有反爬限流的问题,或者需要完整的项目代码,欢迎在评论区交流,我会尽量回复。后续我会分享更多2026年反爬实战的干货,关注我不迷路。
更多推荐



所有评论(0)