服务限流

 概述

  https://javaguide.cn/high-availability/limit-request.html

单机限流

Guava RateLimiter

用于控制并发请求速率的工具类,可以有效地实现限流功能。

通过RateLimiter,我们可以轻松控制系统的吞吐量,防止短时间内请求过多而导致系统过载;

1
2
3
4
5
<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>

  

平滑突发限流

  就是按照指定的速率放令牌到桶里;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class RateLimiterTest {
 
    public static void main(String[] args) {
         //创建一个每秒只允许发出10个令牌的RateLimiter实例
        RateLimiter rateLimiter = RateLimiter.create(10.0); // 指定每秒生成令牌的数量
 
         //模拟多个线程请求
        for (int i = 0; i < 100; i++) {
            // tryAcquire:不会阻塞而是立即返回是否获取令牌成功
            if (rateLimiter.tryAcquire()) {
                System.out.println("请求成功,时间:" + System.currentTimeMillis());
            } else {
                System.out.println("请求被限流,时间:" + System.currentTimeMillis());
            }
        }
    }
 
}
 
结果:
请求成功,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100827
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828
请求被限流,时间:1713167100828

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class RateLimiterTest {
 
    public static void main(String[] args) {
         //创建一个每秒只允许发出10个令牌的RateLimiter实例
        RateLimiter rateLimiter = RateLimiter.create(10.0); // 指定每秒生成令牌的数量
 
        for (int i = 0; i < 100; i++) {
            // acquire()方法尝试获取一个令牌,如果令牌桶中有足够的令牌,则立即返回;否则,阻塞等待直到有足够的令牌
            double acquire = rateLimiter.acquire();
            System.out.println("请求成功,时间:" + System.currentTimeMillis());
        }
    }
 
}
 
结果:
请求成功,时间:1713167182646
请求成功,时间:1713167182746
请求成功,时间:1713167182847
请求成功,时间:1713167182949
请求成功,时间:1713167183046
请求成功,时间:1713167183147
请求成功,时间:1713167183248
请求成功,时间:1713167183346
请求成功,时间:1713167183446
请求成功,时间:1713167183545
请求成功,时间:1713167183647

  

平滑预热限流

  预热时间之内,速率会逐渐提升到配置的速率;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class RateLimiterTest {
 
    public static void main(String[] args) {
 
        // 创建一个每秒只能发出5个令牌的实例
        // 预热时间为3s,也就说刚开始的 3s 内发牌速率会逐渐提升到 0.2s 放 1 个令牌到桶里
        RateLimiter rateLimiter = RateLimiter.create(5, 3, TimeUnit.SECONDS);
        for (int i = 0; i < 200; i++) {
            double sleepingTime = rateLimiter.acquire(1);
            System.out.printf("get 1 tokens: %sds%n", sleepingTime);
        }
    }
 
}
 
 
结果:
get 1 tokens: 0.0ds
get 1 tokens: 0.545473ds
get 1 tokens: 0.512818ds
get 1 tokens: 0.464959ds
get 1 tokens: 0.412942ds
get 1 tokens: 0.355748ds
get 1 tokens: 0.305462ds
get 1 tokens: 0.2494ds
get 1 tokens: 0.203677ds
get 1 tokens: 0.196401ds
get 1 tokens: 0.200042ds
get 1 tokens: 0.198179ds
get 1 tokens: 0.195615ds
get 1 tokens: 0.196237ds
get 1 tokens: 0.197006ds
get 1 tokens: 0.195847ds
get 1 tokens: 0.198456ds
get 1 tokens: 0.195293ds
get 1 tokens: 0.195719ds
get 1 tokens: 0.194725ds

  

posted on   anpeiyong  阅读(5)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示