一个简单的配额限制库。
-
支持基于速率限流(Query Per Second)
-
支持基于计数限流(Capacity)
您可以使用 Maven 下载这个库到您的项目中。请在 pom.xml 中添加我们的 repository 和这个项目:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 此处可以有其他内容,已省略 -->
<repositories>
<repository>
<id>tahiti-nexus-snapshots</id>
<name>Tahiti NEXUS</name>
<url>http://sse.tongji.edu.cn/tahiti/nexus/content/groups/public</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<dependencies>
<!-- 此处可以有其他内容,已省略 -->
<dependency>
<groupId>octoteam.tahiti</groupId>
<artifactId>tahiti-quota</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
除了这个库本身以外,TahitiQuotaLimiter 还依赖于 guava,因此您还需要将以下 jar 下载下来添加到项目中:
当请求次数超过 3 次后,后续的请求将全部失败:
QuotaLimiter limiter = new CapacityLimiter(3);
limiter.tryAcquire(); // true
limiter.tryAcquire(); // true
limiter.tryAcquire(); // true
limiter.tryAcquire(); // false
limiter.tryAcquire(); // false
// ...
超出 5 次/s 频率的请求将失败:
QuotaLimiter limiter = new ThroughputLimiter(5);
// .....
if (limiter.tryAcquire()) {
// 没有超出限额,继续
} else {
// 超出了限额,提示错误或忽略
}
恢复到全部配额都未使用的状态:
QuotaLimiter limiter = new CapacityLimiter(2);
// or ThroughputLimiter
limiter.tryAcquire(); // true
limiter.tryAcquire(); // true
limiter.tryAcquire(); // false
limiter.reset();
limiter.tryAcquire(); // true
limiter.tryAcquire(); // true
limiter.tryAcquire(); // false
一次性进行多次请求,如果全部请求都没有超出配额,则成功,否则全部请求都不会进行。
注意,与多次进行单个请求不同的是,批量请求要么全部成功,要么全部失败。
QuotaLimiter limiter = new CapacityLimiter(4);
// or ThroughputLimiter
limiter.tryAcquire(10); // false, 剩余可用额度小于请求次数, 失败, 不改变任何状态
limiter.tryAcquire(); // true
limiter.tryAcquire(3); // true
limiter.tryAcquire(); // false
注:limiter.tryAcquire()
等价于 limiter.tryAcquire(1)
。
CapacityLimiter 和 ThroughputLimiter 都支持动态扩充或收缩配额:
CapacityLimiter limiter = new CapacityLimiter(2);
limiter.tryAcquire(2); // true
limiter.tryAcquire(); // false
limiter.setCapacity(5);
limiter.tryAcquire(3); // true
limiter.tryAcquire(); // false
ThroughputLimiter limiter = new ThroughputLimiter(1.0);
limiter.setQPS(2.0); // update QPS to 2.0