当前位置: > Linux服务器 > nginx >

Nginx 的 ngx_http_limit_conn_module、ngx_http_limit_req_module中的limit相关配置参数

时间:2020-01-03 11:52来源:linux.it.net.cn 作者:IT
Nginx 的 ngx_http_limit_conn_module、ngx_http_limit_req_module中的limit相关配置参数


ngx_http_limit_req_module 模块(nginx 自带本模块除非编译时使用了–without-http_limit_req_module)

本模块基于漏斗算法(Leaky Bucket)
该算法有两种处理方式(水桶满水之后)

  • Traffic Shaping:暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水。此方式的核心是等待。
  • Traffic Policing:溢出的上方水直接抛弃。此方式的核心是抛弃。

这两种是常见的流速的控制方法。

名称 默认配置 作用域 解读 模块
limit_req_zone 没有默认值,语法 limit_req_zone key zone=name:size rate=rate; http 第一个参数指定key,第二个参数指定zone名称和元数据的内存大小,第三个参数rate指定单位时间的请求数阈值 ngx_http_limit_req_module
limit_req 没有默认值,语法 limit_req zone=name [burst=number] [nodelay]; http, server, location 指定zone的burst大小 ngx_http_limit_req_module
limit_req_log_level limit_req_log_level error; http, server, location 指定触发req limit时打印的日志级别 ngx_http_limit_req_module
实例配置

nginx 配置文件增加配置,为方便测试我将limit_req_zone、limit_req放在http段,使其全局生效。
如果针对各个虚拟主机单独配置,需要注意不能用include将各个虚拟主机(include vhost/*.conf)的方式,经测试此模块不支持这样部署方式(测试版本nginx1.8 其他版本没有测试),需将各个虚拟主机配置在nginx.conf里

http {
...
	limit_req_zone $binary_remote_addr zone=one:10m  rate=1r/s;
	limit_req zone=one burst=5 nodelay;
...

参数说明: 第一段:

  • *$binary_remote_addr :表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址
  • zone=one:10m:表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息*
  • rate=1r/s:表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,即每秒只处理一个请求,还可以有比如30r/m的,即限制每2秒访问一次,即每2秒才处理一个请求。 第二段:
  • zone=one :设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
  • burst=5:重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有5个,超过的请求会直接报503的错误然后返回。
  • nodelay:
    • 如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况。(这里的rate的单位是:r/s)
    • 如果没有设置,则所有请求会依次等待排队 burst参数主要采用了令牌桶算法。令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据数目,并允许突发数据的发送。 令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以发送流量。令牌桶中的每一个令牌都代表一个字节。如果令牌桶中存在令牌,则允许发送流量;如果令牌桶中不存在令牌,则不允许发送流量。因此,如果突发门限被合理地配置并且令牌桶中有足够的令牌,那么流量就可以以峰值速率发送。

令牌桶算法的基本过程如下:

  • 假如用户配置的平均发送速率为10r/s,则每隔0.1秒一个令牌被加入到桶中;
  • 假设桶最多可以存发b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃;
  • 当一个n个字节的数据包到达时,就从令牌桶中删除n个令牌,并且数据包被发送到网络;
  • 如果令牌桶中少于n个令牌,那么不会删除令牌,并且认为这个数据包在流量限制之外;
  • 算法允许最长b个字节的突发,但从长期运行结果看,数据包的速率被限制成常量r。对于在流量限制外的数据包可以以不同的方式处理: - 它们可以被丢弃; - 它们可以排放在队列中以便当令牌桶中累积了足够多的令牌时再传输; - 它们可以继续发送,但需要做特殊标记,网络过载的时候将这些特殊标记的包丢弃。

注意:令牌桶算法不能与另外一种常见算法“漏斗算法(Leaky Bucket)”相混淆。这两种算法的主要区别在于“漏斗算法”能够强行限制数据的传输速率,而“令牌桶算法”在能够限制数据的平均传输数据外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量。

关于添加或不添加burst、nodelay的区别: 请参考:https://blog.csdn.net/hellow__world/article/details/78658041

ngx_http_limit_conn_module (nginx 自带本模块除非编译时使用了–without-http_limit_conn_module)

ngx_http_limit_conn_module 对于一些服务器流量异常、负载过大,甚至是大流量的恶意攻击访问等,进行并发数的限制;该模块可以根据定义的键来限制每个键值的连接数,只有那些正在被处理的请求(这些请求的头信息已被完全读入)所在的连接才会被计数。该模块提供了两个配置参数,limit_conn_zone 和 limit_conn ,其中 limit_conn_zone 只能配置在 http{} 段,而 limit_conn 则可以配置于http{},server{},location{} 区段中。

limit_conn_zone 语法:limit_conn_zone $variable zone=name:size; 配置段:http

该指令描述会话状态存储区域。键的状态中保存了当前连接数,键的值可以是特定变量的任何非空值(空值不会被考虑)。$variable 定义键,zone=name 定义区域名称,主要作用与后面的 limit_conn。size 定义各个键共享内存空间大小

    limit_conn_zone $binary_remote_addr zone=one:10m;

注释:

客户端的IP地址作为键。注意,这里使用的是 binary_remote_addr 变量,而不是 remote_addr 变量。 remote_addr变量的长度为7字节到15字节,而存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。 binary_remote_addr变量的长度是固定的4字节,存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。 1M共享空间可以保存3.2万个32位的状态,1.6万个64位的状态。 如果共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 (Service Temporarily Unavailable) 错误。

limit_conn

语法:limit_conn zone_name number 配置段:http,server,location

该指令指定每个给定键值的最大同时连接数,当超过这个数字时返回503(Service )错误。如(同一IP同一时间只允许有20个连接)
    limit_conn  one  20;

使用注意事项

事务都具有两面性的。ngx_http_limit_conn_module 模块虽说可以解决当前面临的并发问题,但是会引入另外一些问题的。如前端如果有做LVS或反代,而我们后端启用了该模块功能,那不是非常多503错误了?这样的话,可以在前端启用该模块,要么就是设置白名单。


 

(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容