Giriş
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
Maven
Şöyle
yaparız. RequestRateLimiter altta Redis kullanır. Dolayısıyla data-redis gerekir.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifatId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
RequestRateLimiter is one of the many gateway filters offered by SCG. The implementation determines whether a request is allowed to proceed or has exceeded its limit. ...
the gateway comes with one that uses a user’s Principal name. A secured gateway is needed to resolve a user’s principal name, but you have the option to implement the KeyResolver interface to instead resolve a different key from the ServerWebExchange.
You can point to a custom KeyResolver bean (for example, named customKeyResolver) in the configuration by using a SPEL #{@customKeyResolver} expression.
RequestRateLimiter sınfı RequestRateLimiterGatewayFilterFactory tarafından
yaratılır
The provided Redis implementation lets you define the request rate at which users can make calls within a certain time period. It also makes it possible to accommodate sporadic demands while constrained by the defined consumption rate. For example, a configuration can define a replenish rate of 500 requests per second by setting the redis-rate-limiter.replenishRate=500 property and a burst capacity of 1000 request per second by setting the redis-rate-limiter.burstCapacity=1000 property. Doing so limits consumption to 500 requests every second. If a burst in the number of requests occurs, only 1,000 requests are allowed. However, because 1,000 requests are a quota of 2 seconds, the gateway would not route requests for the next second. The configuration also lets you define how many tokens a request would cost by setting the property redis-rate-limiter.requestedTokens property. Typically, it is set to 1.
To use a gateway with a request limiting feature, it needs to be configured with the RequestRateLimiter gateway filter.
spring:
cloud:
gateway:
routes:
- id: route1
uri: http://localhost:8081
predicates:
- Path=/backend
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 500
redis-rate-limiter.burstCapacity: 1000
redis-rate-limiter.requestedTokens: 1
burstCapacity, the total capacity of the token bucket.
replenishRate, the average rate at which the token bucket is filled per second.
KeyResolver Arayüzü
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
Eğer KeyResolver kullanmak istersek şöyle
yaparızspring:
cloud:
gateway:
routes:
- id: route1
uri: http://localhost:8081
predicates:
- Path=/backend
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{customRateLimiter}"
key-resolver: "#{customKeyResolver}"
@Bean
public KeyResolver customKeyResolver {
return exchange -> .... // returns a Mono of String
}
Örnek
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: limit_route
uri: http://httpbin.org:80/get
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
filters:
- name: RequestRateLimiter
args:
key-resolver: '#{@hostAddrKeyResolver}'
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 3
application:
name: gateway-limiter
redis:
host: localhost
port: 6379
database: 0key-resolver, the name of the bean object of the resolver for the throttled key. It uses SpEL expressions to get bean objects from the Spring container based on #{@beanName}.
Hostname özelliğine göre sınırlamak için şöyle
yaparızpublic class HostAddrKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress()
.getAddress().getHostAddress());
}
}
@Bean
public HostAddrKeyResolver hostAddrKeyResolver() {
return new HostAddrKeyResolver();
}
URI'ye göre sınırlamak için şöyle
yaparızpublic class UriKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getURI().getPath());
}
}
@Bean
public UriKeyResolver uriKeyResolver() {
return new UriKeyResolver();
}import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.netty.util.internal.StringUtil;
import reactor.core.publisher.Mono;
public class CustomerKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String apiName = exchange.getRequest().getPath().toString();
List<String> customerIds = exchange.getRequest().getHeaders().get("X-Customer-Id");
if (customerIds != null && ...) {
return Mono.just(customerIds.get(0) + StringUtil.COMMA + apiName);
}
List<String> authHeaders = exchange.getRequest().getHeaders().get("Authorization");
if (authHeaders != null && ...) {
...
}
return Mono.just(StringUtil.EMPTY_STRING);
}
}