基於 Redisson 的限流 小 demo


 

引包:

<!--Redisson插件-->
<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>3.10.2</version>
</dependency>

 

 

java 類:

package com..distributed;

import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class RedisRateLimiter {

    static RedissonClient redisson = null;
    static RRateLimiter myLimiter;

    static {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setConnectionMinimumIdleSize(10);
        //創建Redisson客戶端
        redisson = Redisson.create(config);

        /**
         * 基於Redis的分布式限流器可以用來在分布式環境下現在請求方的調用頻率。
         * 既適用於不同Redisson實例下的多線程限流,也適用於相同Redisson實例下的多線程限流。
         * 該算法不保證公平性。
         */
        myLimiter = redisson.getRateLimiter("my");

        /**
         * Total rate for all RateLimiter instances
         * 作用在所有的RRateLimiter實例
         * OVERALL
         *
         * Total rate for all RateLimiter instances working with the same Redisson instance
         * 作用在同一個Redisson實例創建的 RRateLimiter上面。
         * PER_CLIENT
         *
         * return : 設置是否成功。 對同一個redis服務端,只需要設置一次。如果redis重啟需要重新設置
         */
        boolean bl = myLimiter.trySetRate(RateType.PER_CLIENT, 5, 1, RateIntervalUnit.SECONDS);
    }


    //結合redis,實現分布式的qpi接口限流
    public static void test() {

        CountDownLatch cd = new CountDownLatch(1);
        Random rd = new Random();

        for (int i = 0; i < 20; i++) {
            new Thread(() -> {

                try {
                    cd.await(); //使得當前線程阻塞
                    Thread.sleep(rd.nextInt(1000)); //模擬20個請求的並發,有一點點先后順序的差異
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {

                    //獲取令牌
                    System.out.println(Thread.currentThread().getName() + " : " + myLimiter.tryAcquire());
                }

            }).start();
        }

        cd.countDown();
    }

    public static void main(String[] args) {

        test();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //正常退出 status為0時為正常退出程序,也就是結束當前正在運行中的java虛擬機
        System.exit(0);
    }

}

 

運行結果 只有5個成功 :

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM