点击上方 Java后端,选择 设为星标
优质文章,及时送达
限流算法:令牌桶算法
算法思想是:
-
令牌以固定速率产生,并缓存到令牌桶中;
-
令牌桶放满时,多余的令牌被丢弃;
-
请求要消耗等比例的令牌才能被处理;
-
令牌不够时,请求被缓存。
漏桶算法
-
水(请求)从上方倒入水桶,从水桶下方流出(被处理);
-
来不及流出的水存在水桶中(缓冲),以固定速率流出;
-
水桶满后水溢出(丢弃)。
-
这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
-
limit_req_zone
用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 "leaky bucket"。
-
limit_req_conn
用来限制同一时间连接数,即并发限制。
limit_req_zone 参数配置
Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
-
第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址。
-
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
-
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的。
limit_req zone=one burst=5 nodelay;
-
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。
-
第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。
-
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /search/ {
limit_req zone=one burst=5 nodelay;
}
}
limit_req_zone $anti_spider zone=one:10m rate=10r/s;
limit_req zone=one burst=100 nodelay;
if ($http_user_agent ~* "googlebot|bingbot|Feedfetcher-Google") {
set $anti_spider $http_user_agent;
}
Syntax: limit_req_log_level info | notice | warn | error;
Default:
limit_req_log_level error;
Context: http, server, location
limit_req_log_level notice
延迟的的基本是info。
Syntax: limit_req_status code;
Default:
limit_req_status 503;
Context: http, server, location
ngx_http_limit_conn_module 参数配置
Syntax: limit_conn zone number;
Default: —
Context: http, server, location
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
limit_conn addr 1;
}
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
...
limit_conn perip 10;
limit_conn perserver 100;
}
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
limit_conn_zone $binary_remote_addr zone=addr:10m;
$ remote_addr
,而是使用
$ binary_remote_addr
变量。
$ remote_addr
变量的大小可以从7到15个字节不等。存储的状态在32位平台上占用32或64字节的内存,在64位平台上总是占用64字节。对于IPv4地址,
$ binary_remote_addr
变量的大小始终为4个字节,对于IPv6地址则为16个字节。存储状态在32位平台上始终占用32或64个字节,在64位平台上占用64个字节。一个兆字节的区域可以保持大约32000个32字节的状态或大约16000个64字节的状态。如果区域存储耗尽,服务器会将错误返回给所有其他请求。
Syntax: limit_conn_log_level info | notice | warn | error;
Default:
limit_conn_log_level error;
Context: http, server, location
Syntax: limit_conn_status code;
Default:
limit_conn_status 503;
Context: http, server, location
实战
实例一 限制访问速率
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit;
}
}
实例二 burst缓存处理
来看我们的配置:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4;
}
}
实例三 nodelay降低排队时间
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4 nodelay;
}
}
示例四 自定义返回值
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4 nodelay;
limit_req_status 598;
}
}
默认情况下 没有配置 status 返回值的状态:
Nginx限制访问速率和最大并发连接数模块--limit (防止DDOS攻击)
http://www.cnblogs.com/wjoyxt/p/6128183.html
Nginx 限流
http://colobu.com/2015/10/26/nginx-limit-modules/
关于nginx的限速模块
https://www.cnblogs.com/chenpingzhao/p/4971308.html
Nginx 源代码笔记 - HTTP 模块 - 流控
http://ialloc.org/posts/2014/07/26/ngx-notes-module-http-limit/
Module ngx_http_limit_conn_module
http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
Module ngx_http_limit_req_module
Nginx限速模块初探
如果看到这里,说明你喜欢这篇文章,请 转发、点赞。同时 标星(置顶)本公众号可以第一时间接受到博文推送。
推荐阅读
1. Lambda 表达式入门
2. 卧槽!原来 IOC 这么简单
3. Java 处理 Exception 的 9 个最佳实践
4. 这本 Java 开发手册出炉啦!

《Java技术栈学习手册》
,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。
获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。
喜欢文章,点个在看
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。