Nginx 如何实现有效限流?(深入解析 Nginx 限流方法)

Nginx 实现有效限流的深度解析

Nginx 提供了几种内置机制来实现不同层面的请求限速,以保护服务器资源,防止过度负载或 DDoS 攻击。以下是最常见的限流方法及其详细配置说明:

1. limit_req – 控制并发请求数量

limit_req 指令允许限制在特定时间内到达同一区域的请求数量,它可以应用于整个服务器,某个位置或者更细粒度上。

示例:
limit_req_zone $binary_remote_addr zone=my_limit:10m rate=1r/s;
location /popular {
    limit_req zone=my_limit burst=5 nodelay;
}

在此配置中,“my_limit”是限流区的名字,存储在 10MB 内存中。请求被限制为每秒最多一次(rate=1r/s),并且允许瞬间暴发5个请求(burst=5),立即开始拒绝额外请求(nodelay)。

2. limit_conn – 控制每个来源的连接数

此指令限制单个 IP 地址的并发连接数,适用于防止单一来源的大量连接攻击。

limit_conn_zone $binary_remote_addr zone=my_conn:10m;
server {
    ...
    limit_conn my_conn 5;
}

3. limit_req 与 Lua 模块结合使用

Nginx 的 Lua 模块提供了更灵活的限流策略。例如,你可以根据自定义算法动态计算每个用户的请求速率限制:

limit_req_zone $binary_remote_addr zone=my_limit:10m;
location /api {
    set $limit_status "pass";

    if ($request_uri ~ "^/api/") {
        set_by_lua_block $req_per_minute {
            ngx.req.read_body();
            local redis = require("resty.redis")
            local red = redis:new()
            red:set_timeout(100)
            if not red:connect('127.0.0.1', 6379) then
                ngx.log(ngx.ERR, "failed to connect to Redis")
                return nil
            end

            local key = string.format("%s:%d", ngx.var.remote_addr, ngx.time())
            local val = red:get(key)
            if val == nil then
                red:set(key, 1, "EX", 60)
            else
                if tonumber(val) >= 100 then
                    ngx.log(ngx.INFO, "Too many requests from ", ngx.var.remote_addr)
                    ngx.exit(ngx.HTTP_TOO_MANY_REQUESTS)
                end
                red:incrby(key, 1)
            end
        }

        if $limit_status == "pass" then
            limit_req my_limit;
        end
    }
}

在这个例子中,我们使用 Redis 来存储和追踪每个 IP 在过去一分钟内的请求次数。如果超过了设定的限制,则直接返回 429 Too Many Requests 错误。

4. 第三方模块

此外,还有像 limit_req_module、redis_upstream_health_check_module 等第三方模块提供更多高级功能。例如,redis_upstream_health_check_module 可以与 Redis 集群配合,实现跨机器间共享限流规则。

选择合适的限流策略

不同的场景下,你可能需要选择不同的限流机制。例如,limit_req 更适合于限制单个用户的访问速度,而 limit_conn 则能控制总体并发连接数。结合 Lua 动态计算可以满足更为复杂的业务逻辑,但同时也增加了配置的复杂性。

总之,在设计限流方案时,要考虑业务需求、安全考量和系统资源。合理的限流不仅能提高服务质量,还能有效防御网络攻击。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
赵其鑫的头像赵其鑫管理团队

相关推荐

返回顶部