-
时间窗口 redis zset来实现
-
漏桶算法 因为漏桶的漏出速率是固定的参数,所以,即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使流突发(burst)到端口速率.因此,漏桶算法对于存在突发特性的流量来说缺乏效率.
1) Redis-Cell 2)
- 令牌 RateLimiter
// 每秒产生 10 个令牌(每 100 ms 产生一个) RateLimiter rt = RateLimiter.create(10); for (int i = 0; i < 11; i++) { new Thread(() -> { // 获取 1 个令牌 rt.acquire(); System.out.println("正常执行方法,ts:" + Instant.now()); }).start(); }
-
Nginx 提供了两种限流方式,一是通过
limit_req_zone
和burst
来实现速率限流,二是通过limit_conn_zone
和limit_conn
两个指令控制并发连接的总数控制速率 我们需要使用limit_req_zone 用来限制单位时间内的请求数,即速率限制,示例配置如下: limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; server { location / { limit_req zone=mylimit; } } 以上配置表示,限制每个 IP 访问的速度为 2r/s,因为 Nginx 的限流统计是基于毫秒的,我们设置的速度是 2r/s, 转换一下就是 500ms 内单个 IP 只允许通过 1 个请求, 从 501ms 开始才允许通过第 2 个请求。 我们使用单 IP 在 10ms 内发并发送了 6 个请求的执行结果如下: 从以上结果可以看出他的执行符合我们的预期,只有 1 个执行成功了,其他的 5 个被拒绝了(第 2 个在 501ms 才会被正常执行)。 速率限制升级版 上面的速率控制虽然很精准但是应用于真实环境未免太苛刻了,真实情况下我们应该控制一个 IP 单位总时间内的总访问次数, 而不是像上面那么精确但毫秒, 我们可以使用 burst 关键字开启此设置,示例配置如下: limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; server { location / { limit_req zone=mylimit burst=4; } } burst=4 表示每个 IP 最多允许4个突发请求,如果单个 IP 在 10ms 内发送 6 次请求的结果如下: 从以上结果可以看出,有 1 个请求被立即处理了,4 个请求被放到 burst 队列里排队执行了,另外 1 个请求被拒绝了。 控制并发数 利用limit_conn_zone 和limit_conn 两个指令即可控制并发数,示例配置如下: 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; } 其中 limit_conn perip 10 表示限制单个 IP 同时最多能持有 10 个连接;limit_conn perserver 100 表示 server 同时能处理并发连接的总数为 100 个。
服务实现限流的策略
最新推荐文章于 2024-08-09 09:48:48 发布