对于Nginx接入层限流通常可以使用 Nginx自带的两个模块:
可以对某个key,如按照IP、域名对应的总的网络连接数进行限流。
http {
...
limit_conn_zone $binary_remote_addr zone=perip:10m; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)
limit_conn_log_level error; #配置被限流后日志级别
limit_conn_status 503; #配置被限流后返回的状态码
...
server {
...
#在要限流的location中添加限流逻辑
location /
{
limit_conn perip 2; #存放key和计数器的共享内存区域 和 指定key的最大连接数
}
}
...
access_log /www/wwwlogs/oyhdo.com.log;
error_log /www/wwwlogs/oyhdo.com.error.log;
}
以上配置表示:限制每个IP最大并发连接数为2。
ab测试:并发数5,总请求数5,命令如下:
ab -n 5 -c 5 https://oyhdo.com/
打印access_log结果如下:
http {
...
limit_conn_zone $server_name zone=perserver:10m; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)
limit_conn_log_level error; #配置被限流后日志级别
limit_conn_status 503; #配置被限流后返回的状态码
...
server {
...
#在要限流的location中添加限流逻辑
location /
{
limit_conn perserver 2; #存放key和计数器的共享内存区域 和 指定key的最大连接数
}
}
...
access_log /www/wwwlogs/oyhdo.com.log;
error_log /www/wwwlogs/oyhdo.com.error.log;
}
以上配置表示:限制每个域名最大并发请求连接数为2。
ab测试:并发数5,总请求数5,命令如下:
ab -n 5 -c 5 https://oyhdo.com/
打印access_log结果如下:
可以对某个key,如按照IP、域名对应的请求的平均速率进行限流,有两种用法:平滑模式(delay)、允许突发模式(nodelay),也称为延迟模式和非延迟模式。
http {
...
limit_req_zone $binary_remote_addr zone=perip:10m rate=500r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
limit_conn_log_level error; #配置被限流后日志级别
limit_conn_status 503; #配置被限流后返回的状态码
...
server {
...
#在要限流的location中添加限流逻辑
location /
{
limit_req zone=perip; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
}
}
...
access_log /www/wwwlogs/oyhdo.com.log;
error_log /www/wwwlogs/oyhdo.com.error.log;
}
以上配置表示:限制每秒500个请求,即平均速率为2毫秒一个请求;桶容量(burst)为0;延迟模式
ab测试:并发数2,总请求数10,命令如下:
ab -n 10 -c 2 https://oyhdo.com/
打印access_log结果如下:(虽然允许每秒500个请求,但是桶容量为0,所以流入的请求要么被处理要么被限流,无法延迟处理)
http {
...
limit_req_zone $binary_remote_addr zone=perip:10m rate=2r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
limit_conn_log_level error; #配置被限流后日志级别
limit_conn_status 503; #配置被限流后返回的状态码
...
server {
...
#在要限流的location中添加限流逻辑
location /
{
limit_req zone=perip burst=3; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
}
}
...
access_log /www/wwwlogs/oyhdo.com.log;
error_log /www/wwwlogs/oyhdo.com.error.log;
}
以上配置表示:限制每秒2个请求,即平均速率为500毫秒一个请求;桶容量(burst)为3;延迟模式
ab测试:执行一个req.sh脚本,命令如下:(进行6个并发请求6次URL,休眠300毫秒,重复请求)
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
打印access_log结果如下:(预计超过桶容量3会限制请求,由于算法精度问题会有一些偏差,每轮流入了4个请求,另外做了延迟处理)
http {
...
limit_req_zone $binary_remote_addr zone=perip:10m rate=2r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
limit_conn_log_level error; #配置被限流后日志级别
limit_conn_status 503; #配置被限流后返回的状态码
...
server {
...
#在要限流的location中添加限流逻辑
location /
{
limit_req zone=perip burst=3 nodelay; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
}
}
...
access_log /www/wwwlogs/oyhdo.com.log;
error_log /www/wwwlogs/oyhdo.com.error.log;
}
以上配置表示:限制每秒2个请求,即平均速率为500毫秒一个请求;桶容量(burst)为3;非延迟模式
ab测试:执行一个req.sh脚本,命令如下:
ab -n 6 -c 6 https://oyhdo.com/
sleep 1
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 2
ab -n 6 -c 6 https://oyhdo.com/
打印access_log结果如下:(由于算法精度问题会有一些偏差,第一轮和第六轮流入了4个请求,允许突发请求)