SpringCloudGateway 和 Redis 的速率限制器,总是收到 429 过多的请求

问题描述 投票:0回答:1

我试图仅限制特定端点的 POST 方法,并且“它正在工作”,但无论我等待多少时间或者是否是我的第一个请求,我都会收到 429 错误消息。我尝试在 application.yaml 上配置限制器,但它不起作用,我得到一些结果的唯一方法是使用 @Bean。

我也不知道在.yaml上配置redis的正确方法是什么

我正在使用微服务开发模式,所以我在网关上配置限制器。

pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

<properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.0</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- RATE LIMITER -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

    </dependencies>

application.yaml

server:
  port: 8766

spring:
  profiles:
    active: local

  application:
    name: gateway

#  data:
#    redis:
#      host: localhost
#      port: 4242
  cache:
    type: redis
    redis:
      host: localhost
      port: 4242

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true

          lower-case-service-id: true

      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*"
            allowedHeaders: "*"
            allowedMethods:
              - GET
              - POST
              - PUT
              - PATCH
              - OPTIONS

#      routes:
#        - id: limit
#          uri: http://localhost:8766
#          predicates:
#            - Path=/tech-news/comments/**
#            - Method=POST
#          filters:
#            - name: RequestRateLimiter
#              args:
#                redis-rate-limiter:
#                    replenishRate: 10
#                redis-rate-limiter.replenishRate: 10
#                redis-rate-limiter.burstCapacity: 20
#                redis-rate-limiter.requestedTokens: 1
#                key-resolver: "#{@userKeyResolver}"

GatewayConfig.java:

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import reactor.core.publisher.Mono;

@Configuration``your text``
public class GatewayConfig {

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder routeLocatorBuilder) {
        return routeLocatorBuilder.routes()
                .route(p-> p
                        .path("/tech-news/comments/**")
                        .and()
                        .method(HttpMethod.GET)
                        .filters(f -> f.requestRateLimiter().configure(c -> c.setRateLimiter(redisRateLimiter()).setKeyResolver(userKeyResolver())))
                        .uri("http://localhost:8766")
                ).build();
    }

    @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }

    @Bean
    RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20, 1);
    }

}

我的目标是限制仅对我的“tech-news/comments/**”端点的 POST 请求 但我想要一个可以稍后扩展到其他服务/端点的配置

我想限制为每分钟 1 个请求,但我找不到正确的方法。

spring-boot redis microservices spring-cloud-gateway rate-limiting
1个回答
0
投票

早上好,托雷斯。我设法使用 FASTAPI 解决了您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.