Nginx:限流
📖参考:
概述
流量限制(rate-limiting),是 Nginx 中一个非常实用,却经常被错误理解和错误配置的功能。我们可以用来限制用户在给定时间内 HTTP 请求的数量。
流量限制可以用作安全目的,比如可以减慢暴力密码破解的速率。通过将传入请求的速率限制为真实用户的典型值,并标识目标URL地址(通过日志),还可以用来抵御 DDOS 攻击。更常见的情况,该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。
如何限流
Nginx 的”流量限制”使用漏桶算法(leaky bucket algorithm),该算法在通讯和分组交换计算机网络中广泛使用,用以处理带宽有限时的突发情况。就好比,一个桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;同样,在请求处理方面,水代表来自客户端的请求,水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。
限流使用的模块
Nginx 的 limit 模块主要包括:ngx_http_limit_req_module
、ngx_http_limit_conn_module
、ngx_stream_limit_conn_module
。
其中 ngx_http_limit_req_module
、ngx_http_limit_conn_module
为七层限流,ngx_stream_limit_conn_module
为四层限流。
ngx_http_limit_req_module 模块
语法如下:
1 | # 配置限流区域、桶容量(突发容量,默认0)、是否延迟模式(默认延迟) |
例如:
1 | limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s; |
💡建议:对于大部分部署,我们建议使用 burst 和 nodelay 参数来配置
limit_req
指令。
ngx_http_limit_conn_modul 模块
ngx_http_limit_conn_modul
模块基于 key($binary_remote_addr
或者 server_name
),对网络总连接数进行限流。
👀注意:不是所有的网络连接都会被计数器统计,只有被 Nginx 处理的并且已经读取了整个请求头的连接才会被计数器统计。
语法如下:
1 | # 用于配置限流 key 及存放限流 key 对应的共享内存大小 |
例如:
1 | http{ |
ngx_stream_limit_conn_module 模块
ngx_stream_limit_conn_module
模块在 TCP/UDP 会话的 Pre-access
阶段被处理。
语法如下:
1 | # 为指定的共享内存区域设置参数,该区域将保留各种 key 的状态。 |
例如:
1 | # key 是一个 $binary_remote_addr 变量设置的客户端 IP 地址。$binary_remote_addr 的大小为 IPv4 地址的 4 个字节或 IPv6 地址的 16 个字节。存储状态在 32 位平台上总是占用 32 或 64 字节,在 64 位平台上占用 64 字节。一兆字节区域可以保留大约 32,000 个 32 字节状态或大约 16,000 个 64 字节状态。如果区域存储耗尽,服务器将关闭连接。 |