You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds support for a Bucket4jRateLimiter in server webflux (#2955)
* Adds support for a Bucket4jRateLimiter
* Makes bucket4j-core optional and caffeine integration test scoped
* Adds Bucket4jRateLimiter auto-configuration
* Updates bucket4j to 8.14.0
* Adds customizable header and adapts to async build
* Adds configuration for alternative RefillStyles
* Adds documentation and refillTokens property
Copy file name to clipboardExpand all lines: docs/modules/ROOT/pages/spring-cloud-gateway/gatewayfilter-factories/requestratelimiter-factory.adoc
+83-5Lines changed: 83 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,17 @@ The default implementation of `KeyResolver` is the `PrincipalNameKeyResolver`, w
27
27
By default, if the `KeyResolver` does not find a key, requests are denied.
28
28
You can adjust this behavior by setting the `spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key` (`true` or `false`) and `spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code` properties.
29
29
30
+
The following example configures a `KeyResolver` in Java:
The `RequestRateLimiter` is not configurable with the "shortcut" notation. The following example below is _invalid_:
@@ -81,6 +92,7 @@ The following listing configures a `redis-rate-limiter`:
81
92
82
93
Rate limits below `1 request/s` are accomplished by setting `replenishRate` to the wanted number of requests, `requestedTokens` to the timespan in seconds, and `burstCapacity` to the product of `replenishRate` and `requestedTokens`.
83
94
For example, setting `replenishRate=1`, `requestedTokens=60`, and `burstCapacity=60` results in a limit of `1 request/min`.
95
+
84
96
.application.yml
85
97
[source,yaml]
86
98
----
@@ -99,21 +111,87 @@ spring:
99
111
100
112
----
101
113
102
-
The following example configures a `KeyResolver` in Java:
114
+
This defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available.
115
+
The `KeyResolver` is a simple one that gets the `user` request parameter
116
+
NOTE: This is not recommended for production
117
+
118
+
[[bucket4j-ratelimiter]]
119
+
== Bucket4j `RateLimiter`
120
+
121
+
This implementation is based on the https://bucket4j.com/[Bucket4j] Java library.
122
+
It requires the use of the `com.bucket4j:bucket4j_jdk17-core` dependency as well as one of the https://github.com/bucket4j/bucket4j?tab=readme-ov-file#bucket4j-distributed-features[distributed persistence options].
123
+
124
+
In this example, we will use the Caffeine integration, which is a local cache. This can be added by including the `com.github.ben-manes.caffeine:caffeine` artifact in your dependency management. The `com.bucket4j:bucket4j_jdk17-caffeine` artifact will need to be imported as well.
125
+
126
+
.pom.xml
127
+
[source,xml]
128
+
----
129
+
<dependency>
130
+
<groupId>com.github.ben-manes.caffeine</groupId>
131
+
<artifactId>caffeine</artifactId>
132
+
<version>${caffeine.version}</version>
133
+
</dependency>
134
+
<dependency>
135
+
<groupId>com.bucket4j</groupId>
136
+
<artifactId>bucket4j_jdk17-caffeine</artifactId>
137
+
<version>${bucket4j.version}</version>
138
+
</dependency>
139
+
----
140
+
141
+
First a bean of type `io.github.bucket4j.distributed.proxy.AsyncProxyMananger<String>` needs to be created.
return new CaffeineProxyManager<>(builder, Duration.ofMinutes(1)).asAsync();
110
150
}
111
151
----
112
152
113
-
This defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available.
114
-
The `KeyResolver` is a simple one that gets the `user` request parameter
153
+
The `bucket4j-rate-limiter.capacity` property is the maximum number of requests a user is allowed in a single second (without any dropped requests).
154
+
This is the number of tokens the token bucket can hold.
155
+
Must be greater than zero.
156
+
157
+
The `bucket4j-rate-limiter.refillPeriod` property defines the refill period. The bucket refills at a rate of `refillTokens` per `refillPeriod`. This is a required property and uses the https://docs.spring.io/spring-boot/reference/features/external-config.html#features.external-config.typesafe-configuration-properties.conversion.periods[Spring Boot Period format].
158
+
159
+
The `bucket4j-rate-limiter.refillTokens` property defines how many tokens are added to the bucket in during `refillPeriod`.
160
+
This defaults to `capacity` and must be greater than or equal to zero.
161
+
162
+
The `bucket4j-rate-limiter.requestedTokens` property is how many tokens a request costs.
163
+
This is the number of tokens taken from the bucket for each request and defaults to `1`. Must be greater than zero.
164
+
165
+
The `bucket4j-rate-limiter.refillStyle` property defines how the bucket is refilled. The 3 options are `GREEDY` (default), `INTERVALLY` and `INTERVALLY_ALIGNED`.
166
+
`GREEDY` tries to add the tokens to the bucket as soon as possible. `INTERVALLY`, in opposite to greedy, waits until the whole `refillPeriod` has elapsed before refilling tokens. `INTERVALLY_ALIGNED` is like `INTERVALLY`, but with a specified `timeOfFirstRefill`.
167
+
168
+
The `bucket4j-rate-limiter.timeOfFirstRefill` property is an `Instant` only used when `refillStyle` is set to `INTERVALLY_ALIGNED`.
169
+
170
+
The following example defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available.
115
171
NOTE: This is not recommended for production
116
172
173
+
.application.yml
174
+
[source,yaml]
175
+
----
176
+
spring:
177
+
cloud:
178
+
gateway:
179
+
routes:
180
+
- id: requestratelimiter_route
181
+
uri: https://example.org
182
+
filters:
183
+
- name: RequestRateLimiter
184
+
args:
185
+
bucket4j-rate-limiter.capacity: 20
186
+
bucket4j-rate-limiter.refillTokens: 10
187
+
bucket4j-rate-limiter.refillPeriod: 1s
188
+
bucket4j-rate-limiter.requestedTokens: 1
189
+
190
+
----
191
+
192
+
[[custom-ratelimiter]]
193
+
== Custom `RateLimiter`
194
+
117
195
You can also define a rate limiter as a bean that implements the `RateLimiter` interface.
118
196
In configuration, you can reference the bean by name using SpEL.
119
197
`#{@myRateLimiter}` is a SpEL expression that references a bean with named `myRateLimiter`.
Copy file name to clipboardExpand all lines: spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
0 commit comments