引包:
<!--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個成功 :