大家好,我是威哥。上个月帮朋友的汽配电商平台救了个急——之前用传统的ngx_http_limit_req_modulengx_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年的分布式爬虫面前,完全是“纸糊的”:

  1. 本地限流,分布式场景失效:Nginx是单机的,分布式爬虫集群有1000+个IP,每个IP只发10个请求,总QPS就是10000,单机限流根本压不住。
  2. QPS固定,不够灵活:正常用户的QPS是波动的(比如早上9点-11点是高峰期,QPS会高一点),固定QPS要么高峰期限流正常用户,要么低峰期防不住爬虫。
  3. 只能封IP,维度太单一:2026年的分布式爬虫集群,用的都是高纯净度的住宅IP池、移动运营商IP池,IP换得比翻书还快,封IP根本没用;而且爬虫还会换User-Agent、换Cookie,但传统方案识别不了这些组合特征。
  4. 漏桶算法,突发流量处理差:漏桶算法的出水速度是固定的,正常用户的突发流量(比如秒杀前的预热)会被限流,体验很差。

二、2026最新方案的核心设计思路

针对传统方案的局限性,我设计了这套Nginx+Redis+LuaJIT+多维度特征动态令牌桶的方案,核心思路是:

  1. 分布式限流,Redis做核心:所有限流逻辑、令牌桶、黑名单都存在Redis里,Nginx集群共享,分布式场景下完全生效。
  2. 多维度特征,精准识别爬虫:不再只封IP,而是封IP+JA3+User-Agent+Referer的组合特征,哪怕爬虫换IP,只要JA3或User-Agent不变,还是会被识别。
  3. 动态令牌桶,灵活应对波动:令牌桶的令牌生成速度(QPS)不是固定的,而是根据时间段、用户等级、请求路径动态调整的,高峰期给正常用户多一点令牌,低峰期少一点;VIP用户给更多令牌,普通用户少一点;商品详情页给少一点令牌,首页给多一点。
  4. 突发流量支持,提升用户体验:令牌桶支持预存令牌突发令牌,正常用户的突发流量(比如秒杀前的预热)可以用预存的令牌或突发的令牌,不会被限流。
  5. 自动封禁,无需人工干预:如果某个组合特征的请求,连续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 多维度特征动态令牌桶脚本

这个脚本的作用是:

  1. 生成IP+JA3+User-Agent+Referer的组合特征(可以根据业务需求调整)。
  2. 检查这个组合特征是否在黑名单里,如果在,直接返回-1(拒绝请求)。
  3. 根据时间段、用户等级、请求路径动态计算令牌生成速度(QPS)和令牌桶容量。
  4. 从令牌桶里取令牌,如果有令牌,返回1(允许请求),并更新令牌桶;如果没有令牌,返回0(拒绝请求),并记录限流次数。
  5. 如果限流次数超过阈值,自动把这个组合特征加入黑名单。

把这个脚本保存为/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_modulengx_http_lua_ssl_module,JA3指纹提取失败,只能用IP+User-Agent+Referer代替,拦截率只有80%。后来我配置了这两个模块,JA3指纹提取成功,拦截率提升到了99.5%。


十、总结与建议

最后总结几个能直接落地的经验:

  1. 分布式限流必须用Redis:Nginx本地限流在分布式场景下完全失效,Redis是分布式限流的首选。
  2. 多维度特征比单一IP更有效:2026年的分布式爬虫集群,IP换得比翻书还快,必须封IP+JA3+User-Agent+Referer的组合特征。
  3. 动态令牌桶比固定QPS更灵活:根据时间段、用户等级、请求路径动态调整QPS,既能防住爬虫,又能提升正常用户的体验。
  4. 必须加降级策略:Redis故障、Lua脚本执行失败,都要有降级策略,避免因为反爬组件故障导致平台不可用。
  5. 必须加监控和告警:用Prometheus+Grafana监控Nginx的QPS、限流率、Redis的CPU占用、内存占用,出现问题第一时间告警。

如果大家还有反爬限流的问题,或者需要完整的项目代码,欢迎在评论区交流,我会尽量回复。后续我会分享更多2026年反爬实战的干货,关注我不迷路。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐