限流
本文最后更新于 328 天前,其中的信息可能已经有所发展或是发生改变。
  1. 控制成本 => 限制用户的次数调用次数
  2. 用户在短时间内疯狂使用,导致服务器资源被占满,其他用户无法使用 => 限流

限流的几种算法

1)固定窗口限流

单位时间内允许部分操作

优点:最简单

缺点:可能会出现流量突刺

假设 1 小时只能允许 10 个用户进行操作,在前 59 分钟没有一次操作,然后在第 59 分钟时有 10 次操作,然后在 1 小时 01 分钟时又有 10 次操作,等于 2 分钟内执行了 20 次操作,服务器仍然有高峰危险。

2)滑动窗口限流

单位时间内允许部分操作,但是这个单位时间是滑动的,需要指定一个滑动单位

比如滑动单位 1 min

开始前:

0s 1h 2h

一分钟后

1min 1h 1min 2h 1min

优点:能够解决上述流量突刺的问题,因为第 59 分钟时,限流窗口为 59 分 ~ 1小时 59 分钟,这个时间段内只能接受 10 次请求,只要还在这个窗口内,更多的操作就会被拒绝。

缺点:实现相对复杂,限流效果和滑动单位有关,滑动单位越小,限流效果越好,但往往很难选取到一个特别合适的滑动单位。

3)漏桶限流(推荐)

以固定的速率处理请求(漏水),当请求桶满了后,拒绝请求。

每秒处理10个请求,桶的容量是 10,每0.1秒固定处理一次请求,如果 1 秒内来了 10 个请求;都可以处理完,但如果 1 秒内来了 11 个请求,最后那个请求就会溢出桶,被拒绝。

优点:能够在一定程度上应对流量突刺,能够固定速率处理请求,保证服务器的安全

缺点:没有办法迅速处理一批请求,只能一个一个按顺序来处理(固定速率的缺点)

4)令牌桶限流(推荐)

管理员生成一批令牌,每秒生成 10 个令牌;当用户要操作前,先去拿到一个令牌,有令牌的人就有资格执行操作、能同时执行操作;拿不到令牌的就等着。

优点:能够并发处理同时的请求,并发性能会更高

需要考虑的问题:还是存在时间单位选取的问题

限流的实现

1)本地限流(单机限流):

每个服务器单独限流,一般适用于单体项目,就项目只有一个服务器

Guava RateLimiter

import com.google.common.util.concurrent.RateLimiter;

// 创建一个每秒生成10个令牌的RateLimiter
RateLimiter rateLimiter = RateLimiter.create(10.0); // 指定QPS

public void doSomethingRateLimited() {
    if (rateLimiter.tryAcquire()) {
        // 成功获取令牌,执行受保护的操作
        callThirdPartyAPI();
    } else {
        // 未能获取令牌,拒绝请求或处理回退逻辑
        log.info("调用被限流,超过当前速率限制");
    }
}

2)分布式限流(多机限流):

如果项目有多个服务器,比如微服务,那么建议使用分布式限流。

  1. 把用户的使用频率等数据放到一个集中的存储进行统计,比如 Redis,这样无论用户的请求落到了哪个服务器,都以集中的数据存储内的数据为准(Redisson – 是一个操作 Redis 的工具库
  2. 在网关集中进行限流和统计(比如 Sentinel、Spring Cloud Gateway)

Redisson 限流实现

官方项目仓库和文档:https://github.com/redisson/redisson

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇