Nginx限流常用的两种方式,一种是根据网络流速限制限制访问频率,一种是根据IP限制限制并发连接数。
为什么要用限流呢?
开源人员可以通过限流限制访问速度来防止外部暴力扫描,或者减少密码被暴力破解的可能性。也可以解决流量突发问题(如线上活动导致访问量突增、下班打卡的访问量突增)。简单解释就是限流用于保护服务器不会因为承受不住同一时刻的大量并发请求而宕机,从而保障了服务器的正常运行。
Nginx限流漏桶算法和令牌桶算法的区别
两种算法都能够限制数据传输速率,但令牌桶还允许某种程度的突发传输。因为令牌桶算法只要令牌桶中存在令牌,那么就可以突发的传输对应的数据到目的地,所以更适合流量突发的情形下进行使用。
Nginx限流漏桶方法
定义:漏桶算法是网络世界中流量整形或速率限制时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。也就是我们刚才所讲的情况。漏桶算法提供的机制实际上就是刚才的案例:突发流量会进入到一个漏桶,漏桶会按照我们定义的速率依次处理请求,如果水流过大也就是突发流量过大就会直接溢出,则多余的请求会被拒绝。所以漏桶算法能控制数据的传输速率。
特点:请求以恒定速率流出。当请求进来时放入桶内,遵循先进先出的规则,以设定的速率恒定流出,当桶放满时,不再接收请求。
参数:
limit_conn_zone:定义并发限流
limit_conn_zone $binary_remote_addr zone=myip:10m;
zone:定义限流参数和空间大小
zone=myip:10m
limit_conn:调用实现并发限流
limit_conn zone number
limit_conn_log_level:当达到最大限制连接数后,记录日志的等级。
limit_conn_log_level
limit_conn_status:当达到最大限制连接数后,返回的状态,默认503。
limit_conn_status 404;
用法:
实例:因数据库和服务部署在一台服务器上,下班打卡经常出现服务器崩溃的情况,特此使用限流,限制单个ip地址最高200个并发量,服务器最高并发500个并发量,避免高并发导致数据库超过最大连接数,系统崩溃的情况。
http {
# 定义IP请求并发处理的参数reqip 请求处理空间大小为10m
limit_conn_zone $binary_remote_addr zone=reqip:30m;
# 定义服务端请求并发处理的参数reqServerName 请求空间大小为10m
limit_conn_zone $server_name zone=reqServerName:30m;
}
server {
location / {
# 设置单个ip请求 最高200个并发
limit_conn reqip 200;
# 设置服务器请求最高500个并发
limit_conn reqServerName 500;
}
}
Nginx限流令牌桶方法
定义:令牌桶算法是网络流量整形和速率限制中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。令牌桶算法的机制如下:存在一个大小固定的令牌桶,会以恒定的速率源源不断产生令牌。如果令牌消耗速率小于生产令牌的速度,令牌就会一直产生直至装满整个令牌桶。
特点:请求以恒定速率流入,往桶内以恒定速率往桶里注入令牌,每个请求进来时会获取令牌,若没有获取到令牌则会放弃此请求,当桶满后不再注入令牌。
参数:
limit_req_zone : 定义流速限制
zone : 定义令牌调用参数 参数后面跟的是请求空间大小
rete : 定义令牌生成速率,每秒多少次,1r/s = 每秒生成1个令牌
limit_req :参数调用执行
burst : 定义爆发令牌数
nodelay : 配合burst使用,立即执行
用法:
实例:因外部请求过多,导致系统无法支撑正常使用,特限制单个IP每秒10个人请求服务器,爆发单个IP每秒20个人请求服务器,避免服务器因访问过高导致系统崩溃。
http {
# 定义IP限流参数 mylimit 请求空间10m 请求速率每秒生成10个令牌
# 有令牌就可以访问
limit_req_zone $binary_remote_addr zone=mylimit:30m rate=10r/s;
}
server {
location / {
# 设置请求爆发 请求速率每秒最高生成20个令牌
# nodelay 如果有五个请求获得了令牌会立即执行,第六个没有令牌会报错503
limit_req zone=mylimit burst=20 nodelay;
}
}
函数
$binary_remote_addr : 根据IP地址来定义限流
$server_name : 根据服务器定义限流