

Nginx如何限流
配置基本的限流
limit_req_zone和
limit_req,如下所示:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /login/ {
limit_req zone=mylimit;
proxy_pass http://my_upstream;
}
}
limit_req_zone指令定义了流量限制相关的参数,而
limit_req指令在出现的上下文中启用流量限制(示例中,对于”/login/”的所有请求)。
limit_req_zone指令通常在 HTTP 块中定义,使其可在多个上下文中使用,它需要以下三个参数:
Key - 定义应用限制的请求特性。示例中的 Nginx 变量
remote_addr
,占用更少的空间)Zone - 定义用于存储每个 IP 地址状态以及被限制请求 URL 访问频率的共享内存区域。保存在内存共享区域的信息,意味着可以在 Nginx 的 worker 进程之间共享。定义分为两个部分:通过
zone=keyword
标识区域的名字,以及冒号后面跟区域大小。16000 个 IP 地址的状态信息,大约需要 1MB,所以示例中区域可以存储 160000 个 IP 地址。Rate - 定义最大请求速率。在示例中,速率不能超过每秒 10 个请求。Nginx 实际上以毫秒的粒度来跟踪请求,所以速率限制相当于每 100 毫秒 1 个请求。因为不允许”突发情况”,这意味着在前一个请求 100 毫秒内到达的请求将被拒绝。
limit_req_zone指令设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。所以需要通过添加
limit_req指令,将流量限制应用在特定的 location 或者 server 块。在上面示例中,我们对
/login/请求进行流量限制。

/login/,更准确地说,在前一个请求的 100 毫秒内不能请求该 URL。
处理突发
limit_req中使用 burst 参数:
location /login/ {
limit_req zone=mylimit burst=20;
proxy_pass http://my_upstream;
}
无延迟的排队
location /login/ {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://my_upstream;
}
limit_req指令。
高级配置示例
geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/64 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
location / {
limit_req zone=req_zone burst=10 nodelay;
# ...
}
}
如果变量的值是, limit_key
变量将被赋值为空字符串如果变量的值是, limit_key
变量将被赋值为客户端二进制形式的 IP 地址 两个指令配合使用,白名单内 IP 地址的$limit_key
变量被赋值为空字符串,不在白名单内的被赋值为客户端的 IP 地址。当limit_req_zone
后的第一个参数是空字符串时,不会应用“流量限制”,所以白名单内的 IP 地址(10.0.0.0/8 和192.168.0.0/24 网段内)不会被限制。其它所有 IP 地址都会被限制到每秒 5 个请求。
limit_req指令将限制应用到
/的
location块,允许在配置的限制上最多超过 10 个数据包的突发,并且不会延迟转发。
location包含多limit_req指令
limit_req指令。符合给定请求的所有限制都被应用时,意味着将采用最严格的那个限制。例如,多个指令都制定了延迟,将采用最长的那个延迟。同样,请求受部分指令影响被拒绝,即使其他指令允许通过也无济于事。
http {
# ...
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s;
server {
# ...
location / {
limit_req zone=req_zone burst=10 nodelay;
limit_req zone=req_zone_wl burst=20 nodelay;
# ...
}
}
}
req_zone_wl,并且被限制到每秒 15 个请求。不在白名单内的 IP 地址两个限制能匹配到,所以应用限制更强的那个:每秒 5 个请求。
配置相关功能
2015/06/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, <br>request: "GET / HTTP/1.0", host: "nginx.com"
limiting requests - 表明日志条目记录的是被“流量限制”请求 excess - 每毫秒超过对应“流量限制”配置的请求数量 zone - 定义实施“流量限制”的区域 client - 发起请求的客户端 IP 地址 server - 服务器 IP 地址或主机名 request - 客户端发起的实际 HTTP 请求 host - HTTP 报头中 host 的值
[error]所示(Ngin 以较低级别记录延时请求,一般是 info 级别)。如要更改 Nginx 的日志记录级别,需要使用
limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为 warn:
location /login/ {
limit_req zone=mylimit burst=20 nodelay;
limit_req_log_level warn;
proxy_pass http://my_upstream;
}
发送到客户端的错误代码
limit_req_status指令来设置为其它状态码(例如下面的 444 状态码):
location /login/ {
limit_req zone=mylimit burst=20 nodelay;
limit_req_status 444;
}
指定location拒绝所有请求
location /foo.php {
deny all;
}
总结

文章转载自数据与人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




