简介

nginx有两个限流模块:

1、ngx_http_limit_conn_module 限制速率策略,使用计数器算法

2、ngx_http_limit_req_module 并发限制策略,使用漏桶算法,引用一篇文章来解释该算法:

算法思想是:

  • 水(请求)从上方倒入水桶,从水桶下方流出(被处理);
  • 来不及流出的水存在水桶中(缓冲),以固定速率流出;
  • 水桶满后水溢出(丢弃)。
  • 这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。

限流原理

格式

1
2
limit_req_zone key zone rate
limit_conn_zone key zone

示例

限制请求数

1、limit_req_zone:定义限流策略为限制速率策略

2、$binary_remote_addrremote_addr为存储客户端的ip地址变量,加上binary_为了压缩IP地址

3、zone=req_limit:10mznoe指定内存区域,req_limit为该区域的名称,10m指这块内存区域的大小,

一般10m能存储16W IP 地址访问信息

4、rate=10r/s:指定最大访问速率,10r/s表示每秒最多允许接受10个请求,即100ms内最多有一个请求,当100ms内还有请求,则nginx丢弃该请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
listen 80;
server_name blog.aqcoder.cn;
# limit_req,使用限制速率策略
# burst=5,设置一个大小为 5 的缓冲区(队列),当有大量请求(爆发)过来时,超过了访问频次限制的 # 请求可以先放到这个缓冲区内。
# nodelay,要求立即处理请求;如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回 503,如果 # 没有设置,则所有请求会等待排队。
# limit_req_status 指定请求时报错产生的状态码
limit_req zone=req_limit burst=5 nodelay;
limit_req_status 503;

location /{
root /www/blog.aqcoder.cn;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}

# 当发生指定错误的时候返回50x页面
error_page 502 503 =200 /50x.html;
location = /50x.html {
root /usr/local/nginx/html;
}
}
}

限制连接数

1、limit_req_zone:定义限流策略为并发限制策略

2、$binary_remote_addr:remote_addr为存储客户端的ip地址变量,加上binary_为了压缩IP地址

2、$server_name:server_name表示虚拟主机(server) 同时能处理并发连接的总数

3、zone=perip:10m:znoe指定内存区域,req_limit为该区域的名称,10m指这块内存区域的大小,

一般10m能存储16W IP 地址访问信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
# 定义限流策略
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
# 搜索服务的虚拟主机
server {
location / {
# 使用并发限制策略,表示限制单个 IP 同时最多能持有 1 个连接
# limit_conn perip 1;
# 表示虚拟主机(server) 同时能处理并发连接的总数。只有当 request header 被后端 server # 处理后,这个连接才进行计数
limit_conn perserver 10 ;
limit_conn_status 503;
}
}
}

效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
worker_processes  1;
events {
worker_connections 1024;
}
http {

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

server{
listen 8032;
server_name 119.91.143.195;
location /{
root /www/blog/aaa/;
try_files $uri $uri/ /index.html;
limit_req zone=req_limit burst=1 nodelay;
limit_req_status 503;

# 当发生指定错误的时候返回50x页面
error_page 502 503 =200 /50x.html;
location = /50x.html {
root /usr/local/nginx/html;
}
}
}
}

限流效果

rate=1r/s:速率为1次/秒

burst=1:缓冲1个请求

nodelay:要求立即处理

综上,当我的访问速率超过2r/s时,Nginx会返回503,而error_page代码部分则捕获了503状态码,并返回了/usr/local/nginx/html/50x.html页面

限制连接数效果展示同理,可自行测试。