浅谈Nginx 中的两种限流方式

  

浅谈Nginx 中的两种限流方式

在高并发的场景下,为了保证系统的稳定性和可用性,我们需要对请求进行限流处理。Nginx 作为一款高性能的反向代理和 Web 服务器,也提供了多种限流的方式。本文主要介绍 Nginx 中的两种限流方式:ngx_http_limit_req_modulengx_http_limit_conn_module

ngx_http_limit_req_module

ngx_http_limit_req_module 模块基于令牌桶算法实现,可以让 Nginx 对接口请求进行速率限制,达到防止爬虫或定时任务产生的大量请求拦截。

开启限流

使用 limit_req_zone 指令配置共享内存区域,指定限制请求速率所需要的参数,如下:

http {
    limit_req_zone $binary_remote_addr zone=limit:10m rate=10r/s;
}

这里创建了大小为 10MB 的共享内存区域,用来限制 $binary_remote_addr 唯一标识的客户端的请求速率为 10r/s

serverlocation 块中使用 limit_req 指令启用限流,如下:

location /api {
    limit_req zone=limit burst=20 nodelay;
    proxy_pass http://upstream_server;
}

这里限制 /api 路径的请求速率,同时使用 burst 参数来保存一部分出现峰值请求时依然允许访问(如最开始接受1000个并发的请求,当第1001个请求访问时,它会等待,之后在一秒钟内的20个以内的请求是允许的),使用 nodelay 参数来让请求在达到限流时立即错误返回。

限流错误信息

当达到限流时,Nginx 会返回制定的限流错误信息。可以使用如下配置来制定错误信息:

http {
    limit_req_zone $binary_remote_addr zone=limit:10m rate=10r/s;
    limit_req_status 429;
    limit_req_log_level debug;
    limit_req_log_zone rate_limit_log;
}

server {
    location /api {
        limit_req zone=limit burst=20 nodelay;
        limit_req_status 444;
        limit_req_log_rate 1;
        limit_req_log_rate_after 1m;
        limit_req_log_level info;
        limit_req_log_zone rate_limit_log;
        proxy_pass http://upstream_server;
    } 
}

这里使用 limit_req_status 配置错误状态码,使用 limit_req_log_level 配置日志等级,使用 limit_req_log_zone 配置日志存储区域。日志可以提供限流的详细信息,并帮助分析限流情况。

ngx_http_limit_conn_module

ngx_http_limit_req_module 不同,ngx_http_limit_conn_module 模块基于连接数限制请求速率,常用于限制来自同一 IP 地址的并发请求。

开启限流

使用 limit_conn_zone 指令配置共享内存区域,指定连接数限制所需要的参数,如下:

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}

这里创建了大小为 10MB 的共享内存区域,用来限制 $binary_remote_addr 唯一标识的客户端的连接数。

serverlocation 块中使用 limit_conn 指令启用限流,如下:

location /api {
    limit_conn conn_limit 10;
    proxy_pass http://upstream_server;
}

这里限制 /api 路径的并发连接数不能超过 10 个。

限流错误信息

ngx_http_limit_req_module 类似,使用 limit_conn_statuslimit_conn_log_level 参数来配置连接数限制错误状态码和日志等级,使用 limit_conn_log_zone 指令来配置共享内存日志区域。通常与一些防火墙配合使用,用户若是用了代理服务器,则可以伪造ip来增大攻击强度。所以该模式有一定的缺陷,需要考虑更多情况。

综上所述,ngx_http_limit_req_module 更适合限制请求速率;ngx_http_limit_conn_module 更适合限制连接数。在实际使用时,可以根据自身情况结合使用。

相关文章