1.场景描述
例如网站首页采取二级缓存操作,减少对数据库和redis的压力,但是遇到恶意请求还是不能有效的缓解压力,限流就能起到保护措施的作用了
2.nginx限流
nginx提供了两种限流方案:
- 控制请求速率
- 控制并发连接数
3.控制速率
nginx常用控制速率的方式之一就是采用漏桶算法
3.1漏桶算法实现控制速率限流
概述:漏桶算法思想就是水(请求)滴入漏桶漏桶里,漏桶以一定速率出水(响应速率),当水滴入的速率过大时会溢出漏桶(访问速率大于响应速率),然后就拒绝请求,漏桶算法能强转限制数据的传输速率

配置示例
在nginx的nginx.conf配置文件
http{
limit_req_zone $binary_remote_addr zone=myratelimit:10m rate=2r/s;
...
server{
...
location / {
limit_req zone=myratelimit; burst=5;
}
}
}
}具体配置示例
修改/usr/local/openresty/nginx/conf/nginx.conf:
#user nobody;
user root root;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet‐stream;
#log_format main '$remote_addr ‐ $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main; sendfile on;
#tcp_nopush on; #keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
limit_req_zone $binary_remote_addr zone=myratelimit:10m rate=2r/s;
server {
listen 8081;
server_name localhost;
charset utf‐8;
location / {
limit_req zone=myratelimit;
root html;
index index.html index.htm;
}
}
}需要关注以下配置
limit_req_zone $binary_remote_addr zone=myratelimit:10m rate=2r/s;
server {
listen 8081;
server_name localhost;
charset utf‐8;
location / {
limit_req zone=myratelimit;
root html;
index index.html index.htm;
}
}
}说明:
- 1.binary_remote_addr 是一种key,表示基于 remote_addr(客户端ip) 来做限流
- 2.zone=myratelimit:10m :表示能存储的访问ip的地址,1m能存储16000ip地址的访问信息,10m可以存储16w ip地址访问信息
- 3.rate用于设置最大访问速率,rate=2r/s 表示每秒能处理2个请求,也就是每500毫秒处理一次请求,若1s内再有请求就会被拒绝
- 4.location /:拦截的请求,表示location下所有的请求
3.2突发性限流
场景:当正常流量突然增大,超出的请求将被拒绝,无法处理突发流量,可以结合burst参数
server {
location / {
limit_req zone=myratelimit burst=5;
root html;
index index.html index.htm;
}
}burst: 会将超出的5个请求放入队列中,按照处理速率处理,会一个个进行处理.
但是会造成请求的等待时间过长,为了解决这个问题,可以加关键字 nodelay,就会一次性的处理这些请求如
server {
location / {
limit_req zone=myratelimit burst=5 nodelay;
root html;
index index.html index.htm;
}
}nginx实现限流的总结
nginx限流采用的算法是漏桶算法,水滴入到漏桶中,再按一定速率流出,当滴入的速率大于流出的速率,就会水溢出,也就是请求速率大于处理速率的时候就会拒绝请求。
具体的做法是 在nginx.conf文件中 配置rate 处理速率,配置漏桶能存储的最大存储量,1m能存储16000个ip地址的访问信息
burst: nodelay 能处理突发性请求
网关gatway实现限流
使用场景:限制客户端访问服务端微服务的流量
gatway是采用令牌桶算法实现限流的,配置加入令牌的速率,和令牌桶能放入的最大令牌数量,只有请求获得了令牌才能访问,没有获得令牌就会拒绝访问,令牌桶算法是基于redis实现的,默认使用redis的ratelimter限流算法实现的
具体步骤:
- 1.添加依赖
- 2.在启动类中定义方法返回对象 keyresolver
@springbootapplication
@enableeurekaclient
public class gatewayapplication {
public static void main(string[] args) {
springapplication.run(gatewayapplication.class,args);
}
/**
* 通过keyresolver来指定限流的key
* @return
*/
@bean
public keyresolver ipkeyresolver() {
return new keyresolver() {
@override
public mono<string> resolve(serverwebexchange exchange) {
return mono.just(exchange.getrequest().getremoteaddress().gethostname());
}
};
}
}- 3.在配置中声明令牌产生的速率,令牌桶的大小
filters:
- stripprefix= 1
- name: requestratelimiter #请求数限流 名字不能随便写
args:
key-resolver: "#{@ipkeyresolver}"
redis-rate-limiter.replenishrate: 1 #令牌桶每秒填充平均速率
redis-rate-limiter.burstcapacity: 1 #令牌桶总容量步骤总结
首先引入依赖,在springboot启动类中,指定限流的限流指标,通过@bean交由ioc管理,例如声明一个ipkeyresolver,以ip作为限流的指标。
在配置文件中,配置令牌桶每秒填充的速率和令牌桶总容量,限流的指标。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论