限流在业务层操作上来看有两种手段:
- HTTP协议限流做在
TLB(网关层) - RPC协议限流做在
Service Mesh - 业务逻辑限流会通过特殊的算法实现
在实现原理上:
- TLB一般使用
Nginx实现
Nginx实现
Nginx实现的限流底层算法就是“漏斗算法”
IP限流
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit;
}
}
每秒2次, 每500ms一次, 意思是同一个IP请求后下一个只有在500ms后请求才能生效
并发连接数限流
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
...
limit_conn perip 10;
limit_conn perserver 100;
}
分别表示:
- 同一IP同时做多10个并发链接
- 总共同时不能超过100个并发链接
服务端算法
时间窗口算法
使用redis的zset, score是请求的时间, key是请求的ip值
当一个ip的请求到来时, 先删除一个时间周期前的数据
ZREMRANGEBYSCORE key min max
min是0, max是now()-period, now是当前时间戳, period是周期时间
然后再计算当前周期内已请求的次数:
ZCARD key
如果返回的个数大于限制值, 则说明超过限流了, 否则:
ZADD key now() ip_info`
disadvantages:
如果限流值很大, zset的链就会很长, 很占空间, 也会影响性能
漏斗算法/令牌桶算法
使用redis-cell现成的cl.throttle命令:
- 参数99表示桶容量是100
- 参数1 10 表示每10s给桶入1个
- 40表示这次取40个
Ref
- Summary of xianliu : juejin.cn/post/684490…