Nginx下limit_req模块限制访问频次
最近实际开发过程中,发现部分服务资源访问503 Service Temporarily Unavailable,查找后证实是在对nginx做了限速以后,限速做的太低了超过访问次数直接拒绝访问返回503错误。 nginx 可以使用ngx_http_limit_req对服务器资源请求进行限制。
该模块使用漏斗算法(Leaky Bucket),该算法有两种处理方式Traffic Shaping和Traffic Policing 在桶满水之后,常见的两种处理方式为: 1.暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水。 2.溢出的上方水直接抛弃。
将水看作网络通信中数据包的抽象,则方式1起到的效果称为Traffic Shaping,方式2起到的效果称为Traffic Policing 由此可见,Traffic Shaping的核心理念是”等待”,Traffic Policing的核心理念是”丢弃”。它们是两种常见的流速控制方法
nginx中该模块的使用配置示例
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /search/ {
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的
第二段配置
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应 第二个参数:burst=5,这个配置的意思是设置一个大小为5的缓冲区当有大量请求过来时,超过了访问频次限制的请求可以先放到这个缓冲区内 第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队
接下去举例来看, 更为直观点。
案例1: 设置条件: 速率qps=1, 峰值burst=5, 延迟请求,即没有nodelay参数 效果: 严格按照漏桶速率qps=1处理每秒请求,由于burst=5,所以当一秒内接受到的请求数载1到5之间的时候,没有被处理的请求,会被暂时挂起,相当于存储在漏桶中,一共能存储5个;当前1秒处理一个, 剩下的会被延迟处理 如果请求数超过了burst的限制,则会直接返回503;客户端只要控制并发在峰值burst内,就不会触发limit_req_error_log
案例2: 设置条件:速率qps=1, 峰值burst=5, 不延迟请求, 即有nodelay参数 效果:加了nodelay之后,漏桶控制一段时长内的平均qps = 漏桶速率,但是允许瞬时的峰值qps 大于 漏桶qps。 峰值是最高的qps=brust + qps - 1 比如一开始的时候,如果一下子过来了5个请求,虽然qps=1,但是由于有burst=5,瞬时的峰值能够到达qps=5, 这个5个请求能够同时被处理并返回 ;但是由于设定了漏桶速率qps=1,所以在接下去的5秒时间段内,不能再接受其他请求