几种限流器(RateLimiter)原理与实现
來源:https://blog.csdn.net/netyeaxi/article/details/104270337
限流器(RateLimiter)主要有兩種算法:
漏桶算法
令牌桶算法
它們都是網絡世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)時經常使用的算法。
漏桶算法
漏桶算法(Leaky Bucket),它的主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便為網絡提供一個穩定的流量。
漏桶可以看作是一個帶有常量服務時間的單服務器隊列,如果漏桶(包緩存)溢出,那么數據包會被丟棄。 在網絡中,漏桶算法可以控制端口的流量輸出速率,平滑網絡上的突發流量,實現流量整形,從而為網絡提供一個穩定的流量。
如圖所示,把請求比作是水,水來了都先放進桶里,并以限定的速度出水,當水來得過猛而出水不夠快時就會導致水直接溢出,即拒絕服務。
令牌桶算法
令牌桶算法(Token Bucket),用來控制發送到網絡上的數據的數目,并允許突發數據的發送。
令牌桶算法的原理是系統會以一個恒定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務。從原理上看,令牌桶算法和漏桶算法是相反的,一個“進水”,一個是“漏水”。
漏桶算法&令牌桶算法的區別
漏桶算法與令牌桶算法的區別在于,漏桶算法能夠強行限制數據的傳輸速率,令牌桶算法能夠在限制數據的平均傳輸速率的同時還允許某種程度的突發傳輸。
需要注意的是,在某些情況下,漏桶算法不能夠有效地使用網絡資源,因為漏桶的漏出速率是固定的,所以即使網絡中沒有發生擁塞,漏桶算法也不能使某一個單獨的數據流達到端口速率。因此,漏桶算法對于存在突發特性的流量來說缺乏效率。而令牌桶算法則能夠滿足這些具有突發特性的流量。通常,漏桶算法與令牌桶算法結合起來為網絡流量提供更高效的控制。
下面介紹Java中一些實現了令牌桶算法的常用組件。
單機限流
1、resilience4j-ratelimiter
https://resilience4j.readme.io/docs/ratelimiter
<dependency>
? ? <groupId>io.github.resilience4j</groupId>
? ? <artifactId>resilience4j-ratelimiter</artifactId>
? ? <version>1.3.1</version>
</dependency>
RateLimiterConfig config = RateLimiterConfig.custom()
? .limitRefreshPeriod(Duration.ofMillis(1))
? .limitForPeriod(10)
? .timeoutDuration(Duration.ofMillis(25))
? .build();
?
// Create registry
RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config);
?
// Use registry
RateLimiter rateLimiterWithDefaultConfig = rateLimiterRegistry
? .rateLimiter("name1");
?
RateLimiter rateLimiterWithCustomConfig = rateLimiterRegistry
? .rateLimiter("name2", config)
2、Guava: Google Core Libraries for Java
https://github.com/google/guava
<dependency>
? <groupId>com.google.guava</groupId>
? <artifactId>guava</artifactId>
? <version>28.2-jre</version>
? <!-- or, for Android: -->
? <version>28.2-android</version>
</dependency>
RateLimiter limiter = RateLimiter.create(1);//限制qps最大為1
System.out.println(limiter.acquire()); //輸出阻塞的時間
?
分布式限流
1、Redisson - Redis Java client
https://github.com/redisson/redisson
<dependency>
? ?<groupId>org.redisson</groupId>
? ?<artifactId>redisson</artifactId>
? ?<version>3.12.1</version>
</dependency>
Config config = Config.fromYAML(new File("config-file.yaml"));
RedissonClient redisson = Redisson.create(config);
RRateLimiter rateLimiter = redisson.getRateLimiter("myRateLimiter");
?2、alibaba - Sentinel
https://github.com/alibaba/Sentinel
https://github.com/alibaba/Sentinel/wiki/介紹
<dependency>
? ? <groupId>com.alibaba.csp</groupId>
? ? <artifactId>sentinel-core</artifactId>
? ? <version>1.8.1</version>
</dependency>
private static void initFlowRules(){
? ? List<FlowRule> rules = new ArrayList<>();
? ? FlowRule rule = new FlowRule();
? ? rule.setResource("HelloWorld");
? ? rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
? ? // Set limit QPS to 20.
? ? rule.setCount(20);
? ? rules.add(rule);
? ? FlowRuleManager.loadRules(rules);
}
public static void main(String[] args) {
? ? // 配置規則.
? ? initFlowRules();
?
? ? while (true) {
? ? ? ? // 1.5.0 版本開始可以直接利用 try-with-resources 特性
? ? ? ? try (Entry entry = SphU.entry("HelloWorld")) {
? ? ? ? ? ? // 被保護的邏輯
? ? ? ? ? ? System.out.println("hello world");
?? ?} catch (BlockException ex) {
? ? ? ? ? ? // 處理被流控的邏輯
?? ? ? ?System.out.println("blocked!");
?? ?}
? ? }
}
參考文檔
接口限流算法:漏桶算法和令牌桶算法
https://my.oschina.net/u/4129361/blog/3053350
漏桶算法&令牌桶算法理解及常用的算法
https://www.jianshu.com/p/c02899c30bbd
————————————————
版權聲明:本文為CSDN博主「netyeaxi」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/netyeaxi/article/details/104270337
總結
以上是生活随笔為你收集整理的几种限流器(RateLimiter)原理与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Liskov替换原则(LSP)
- 下一篇: ActiveMQ消费者平滑关闭