Nginx http_limit_req_module 限制每个客户端请求数

 

Nginx限制并发


limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”(用来限制用户请求速率)

The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a single IP address. The limitation is done using the “leaky bucket” method.

Example Configuration

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

Directives

Syntax:limit_req zone=name [burst=number] [nodelay | delay=number];
Default:
Context:httpserverlocation

Sets the shared memory zone and the maximum burst size of requests. If the requests rate exceeds the rate configured for a zone, their processing is delayed such that requests are processed at a defined rate. Excessive requests are delayed until their number exceeds the maximum burst size in which case the request is terminated with an error. By default, the maximum burst size is equal to zero. For example, the directives

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

allow not more than 1 request per second at an average, with bursts not exceeding 5 requests.

If delaying of excessive requests while requests are being limited is not desired, the parameter nodelay should be used:

limit_req zone=one burst=5 nodelay;

The delay parameter (1.15.7) specifies a limit at which excessive requests become delayed. Default value is zero, i.e. all excessive requests are delayed.

There could be several limit_req directives. For example, the following configuration will limit the processing rate of requests coming from a single IP address and, at the same time, the request processing rate by the virtual server:

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;

server {
    ...
    limit_req zone=perip burst=5 nodelay;
    limit_req zone=perserver burst=10;
}

These directives are inherited from the previous level if and only if there are no limit_req directives on the current level.

 

什么是漏桶算法?


我们假设系统是一个漏桶,当请求到达时,就是往漏桶里“加水”,而当请求被处理掉,就是水从漏桶的底部漏出。水漏出的速度是固定的,当“加水”太快,桶就会溢出,也就是“拒绝请求”。从而使得桶里的水的体积不可能超出桶的容量。​主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。limit request做的事情就是把突发的流量限制为恒定的每秒处理多少请求

 

 

limit_req_module  —— 请求频率限制


limit_req_zone key zone=name:size rate=rate;

rate: 以秒为单位限制多少个

context:http

eg: limit_req_zone $binary_remote_addr zone=req_zone:1m rate=10r/s;(1)

用binary_remote_addr 代替remot_addr以节省配置的1M空间的使用,

创建一个名称为req_zone的空间,存储所有请求的客户端ip,空间大小1M,用于限制同一个客户端ip每秒10次的请求频度(rate是用来限制每秒的请求数量)

 

limit_req zone=name [burst=number] [nodelay];

context: http,server,location

eg:  limit_req zone=req_zone; (2)

       limit_req zone=req_zone burst=3;  

       limit_req zone=req_zone burst=5, nodelay; // rate=10r/s 的意思是允许1秒钟不超过10个请求,burst=5 表示最大延迟请求数量不大于5。 如果太过多的请求被限制延迟是不需要的 ,这时需要使用nodelay参数,服务器会立刻返回503状态码。

 

日志


 

 

测试


(1)不加burst nodelay

limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;  --每分钟只能处理2个请求,加上这样的限制是为了更好的看到效果

server {
	root html/;
	error_log logs/myerror.log info;
	
	location /{
		limit_conn_status 500;
		limit_conn_log_level  warn;
		#limit_rate 50;  --把限速也去掉了,因为现在不需限制客户端并发
		#limit_conn addr 1;
		#limit_req zone=one burst=3 nodelay;
		limit_req zone=one;
	}
}



[root@www proc]# curl 192.168.179.99/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


[root@www proc]# curl 192.168.179.99/index.html  --可以看到当第二次去访问的时候出现了503
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>


日志如下:
2020/07/23 10:24:59 [error] 1989#0: *35 limiting requests, excess: 0.210 by zone "one", client: 192.168.179.100, server: localhost, request: "GET /index.html HTTP/1.1", host: "192.168.179.99"
2020/07/23 10:24:59 [info] 1989#0: *35 client 192.168.179.100 closed keepalive connection

(2)加上burst  nodelay

limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;

server {
	server_name limit.taohui.tech;
	root html/;
	error_log logs/myerror.log info;
	
	location /{
		limit_conn_status 500;
		limit_conn_log_level  warn;
		#limit_rate 50;
		#limit_conn addr 1;
		limit_req zone=one burst=3 nodelay;  --现在burst=3,在共享内存当中已经达到了每分钟请求两次的上线了,但是因为有burst,还可以再次访问
		#limit_req zone=one;
	}
}




[root@www proc]# curl 192.168.179.99/index.html----------第一次
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@www proc]# curl 192.168.179.99/index.html ----------------第二次
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@www proc]# curl 192.168.179.99/index.html  -----------第三次
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@www proc]# curl 192.168.179.99/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@www proc]# curl 192.168.179.99/index.html        --------第四次返回503
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>

2020/07/23 10:26:47 [info] 1996#0: *36 client 192.168.179.100 closed keepalive connection
2020/07/23 10:26:50 [info] 1996#0: *37 client 192.168.179.100 closed keepalive connection
2020/07/23 10:26:51 [info] 1996#0: *38 client 192.168.179.100 closed keepalive connection
2020/07/23 10:27:01 [info] 1996#0: *39 client 192.168.179.100 closed keepalive connection
2020/07/23 10:27:04 [error] 1996#0: *40 limiting requests, excess: 3.437 by zone "one", client: 192.168.179.100, server: localhost, request: "GET /index.html HTTP/1.1", host: "192.168.179.99"
2020/07/23 10:27:04 [info] 1996#0: *40 client 192.168.179.100 closed keepalive connection

(3)限制并发和限制请求优先级(request优先级>connect优先级)

limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;

server {
	server_name limit.taohui.tech;
	root html/;
	error_log logs/myerror.log info;
	
	location /{
		limit_conn_status 500;
		limit_conn_log_level  warn;
		limit_rate 50;
		limit_conn addr 1;
		#limit_req zone=one burst=3 nodelay;
		limit_req zone=one;
	}
}
[root@www ~]#  curl 192.168.179.99
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

[root@www ~]#  curl 192.168.179.99  --返回503,因为每分钟只能处理一条请求,所以limit request生效了,但是其实第二次访问这个URL的时候限制连接也生效了,但是返回的还是503,而不是500.
因为limit request模块在limit connect之前。reques执行了connect就没有机会得到执行
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>


日志如下:
2020/07/23 10:30:08 [error] 2023#0: *42 limiting requests, excess: 0.649 by zone "one", client: 192.168.179.100, server: localhost, request: "GET /index.html HTTP/1.1", host: "192.168.179.99"
2020/07/23 10:30:14 [info] 2023#0: *41 client 192.168.179.100 closed keepalive connection
2020/07/23 10:30:15 [info] 2023#0: *42 client 192.168.179.100 closed keepalive connection

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值