服务限流

 概述

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

单机限流

Guava RateLimiter

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

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

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>

  

平滑突发限流

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

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

  

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

  

平滑预热限流

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

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 2024-04-15 15:48  anpeiyong  阅读(20)  评论(0)    收藏  举报

导航