Nginx 限制ip的访问频率
limit_conn_zone是限制同一个IP的连接数。而一旦连接建立之后 。客户端就会通过这次的连接发送多次请求,那么在此期间的请求频率和速度进行限制就需要limit_req_zone
首先了解限制连接数 在Nginx中http区块的配置:
limit_conn_zone $binary_remote_address zone=asia; 10m;
# 这个配置的意思就是定义一个名为 asia的limit_req_zone用来存储session
# 内存为10m大小
然后在nginx的server区块配置如下;
limit_conn asia 2;
# 单个客户端ip与服务器的连接数
完整示例如下:
http {
limit_conn_zone $binary_remote_addr zone=asia:10m;
#limit_conn_zone $server_name zone=perserver:10m
server {
limit_conn asia 10; #单个客户端ip与服务器的连接数.
#limit_conn perserver 100; #限制与服务器的总连接数
}
...
}
解析:
一个在server区块,
asia进行关联的
可以作用于某个目录或者一定类型的资源文件如html.jpg....等进行并发连接限制
既然有了这么一层连接数的限制,
就相当于限制了nginx了客户端之间的管道个数
那么浏览器通过管道进行请求运输,就相当于自来水管道中放水,
水的流速和管道的另外一端肯定是有影响的。
所以为了防止恶意放水用户,也就是不信任的客户端通过这个管道进行疯狂输出
【不是那个疯狂输出别想歪了。。】
对我们的服务器CPU资源造成高负载就必须对其限制。
请求速率限制http区块配置:
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
请求速率限制server区块配置:
limit_req_zone=one burst=10;
这里就引出了一个漏桶算法的东西,burst漏桶原理,结合rate速率,达到每秒5个请求(rate=5r/s)
(此图摘自某度)
burst=10:允许超过频率rate限制的请求数不多于10个
当每秒请求超过5个 但是在10个以下,也就是每秒请求的数量在5-10之间的请求将被延时delay,虽然没有明确的定义delay,默认就是延时的,因为漏桶其实类似队列Queue或消息系统,
当每秒请求数量超过最低速率每5个请求时,多余的请求将会进入这个队列排队等 待。如同机场安检,一次放入5个 。多余5个 。小于10个排队等待
注:这里的队列或者漏桶是以秒为单位的
如果每秒的请求超过10个 ,也就是超出了burst的限制 。那么也不用排队,而是直接回绝返回 503错误(Service Temporarily Unavailable 服务暂时不可用)
-
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=one burst=10 nodelay;
这表示,如果每秒请求在5-10个之间会尽快完成,也就是以每秒10个速率完成,超过每秒10+5也就是15个就立即返回503,因此nodelay实际没有了延时,也就取消了队列等候过渡。
在Twitter Facebook LinkedIn这类大型网站中,由于访问量巨大,通常会在http服务器后面放置一个消息队列,比如Apache Kafka,用来排队大量请求,因此,对于中小型网站,推荐使用delay方案,而不要写明nodelay,但是网络上其他各种文章几乎都是推荐nodelay.
最后,一个带宽限制,如下:
limit_rate 50k;
limit_rate_after 500k;
当下载的大小超过500k以后,以每秒50K速率限制。
上面总结了三个限速限流设置方式,还有一种能够防止POST攻击,黑客通过发出大量POST请求对网站各种URL进行试探攻击,可以通过下面方式防止:
http {
... #nginx.conf 配置
#如果请求类型是POST 将ip地址映射到 $limit 值
map $request_method $limit {
default "";
POST $binary_remote_addr;
}
#创造10mb zone内存存储二进制ip
limit_req_zone $limit zone=my_zone:10m rate=1r/s;
}