Quarkus Bucket4j
Bucket4J is a Java rate-limiting library based on the token-bucket algorithm. Bucket4j is a thread-safe library that can be used in either a standalone JVM application, or a clustered environment. It also supports in-memory or distributed caching via the JCache (JSR107) specification. This extension allow you to control the request rate sent to your application by using a dead simple API.
Installation
If you want to use this extension, you need to add the io.quarkiverse.bucket4j:quarkus-bucket4j
extension first to your build file.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.bucket4j</groupId>
<artifactId>quarkus-bucket4j</artifactId>
<version>1.0.4</version>
</dependency>
Getting Started
Throttling a Method
Annotate the method that need to be throttled with @RateLimited
@ApplicationScoped
public static class RateLimitedMethods {
@RateLimited(bucket = "group1")
public String limited() {
return "LIMITED";
}
}
You can also annotate a class, in that case all methods in the class are throttled
@ApplicationScoped
@RateLimited(bucket = "group1")
public static class RateLimitedMethods {
public String limited() {
return "LIMITED";
}
}
And add a limit group using the same bucket id in the configuration:
# burst protection
quarkus.rate-limiter.buckets.group1.limits[0].permitted-uses: 10
quarkus.rate-limiter.buckets.group1.limits[0].period: 1S
# fair use
quarkus.rate-limiter.buckets.group1.limits[1].permitted-uses: 100
quarkus.rate-limiter.buckets.group1.limits[1].period: 5M
or with yaml:
quarkus:
rate-limiter:
buckets:
group1:
limits:
- permitted-uses: 10
period: 1S
- permitted-uses: 100
period: 5M
The bucket can contain multiple limits that will all be enforced.
Bucket Sharing
By default, if multiple methods share the same bucket id, each method has its own quota. You can change this behaviour by enabling the shared option in the configuration.
# burst protection
quarkus.rate-limiter.buckets.group1.shared: true
quarkus.rate-limiter.buckets.group1.limits[0].permitted-uses: 10
quarkus.rate-limiter.buckets.group1.limits[0].period: 1S
Population Segmentation
If you want to perform the throttling per user, simply specify an IdentityKeyResolver either in the bucket config or in the RateLimited annotation. If a value is specified in the annotation, it will take precedence over the config. The default one is the ConstantResolver, which will cause the segmentation to be disabled.
@ApplicationScoped
public static class RateLimitedMethods {
@RateLimited(bucket = "group1", identityResolver = IpResolver.class)
public String limitedByIp() {
return "LIMITED";
}
}
IpResolver is provided out of the box. if you want a more complex segmentation, you can implement your own resolver. A custom resolver must be a valid CDI Bean.
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
rate limiter will be completely disabled if false Environment variable: |
boolean |
|
Maximum number of entries in the underlying cache Environment variable: |
int |
|
Duration during which the bucket is kept after last refill if untouched Environment variable: |
Duration |
|
Identity resolver allow to segment the population. Each resolved identity key will have its own quota. this must be a valid CDI bean implementing IdentityResolver. Environment variable: |
string |
|
limits enforced for this bucket Environment variable: |
list of Limit |
required |
If true, permitted uses are shared for all methods using the same bucket id. If false, each method has its own quota. Environment variable: |
boolean |
|