es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Spring WebFlux: límite de velocidad del WebClient.

Dado que creo mi WebClient utilizando el patrón builder(), algo así como esto:

WebClient.builder()
    .uriBuilderFactory(defaultUriBuilderFactory)
    .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
    .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
    .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
    .defaultHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate")
    .exchangeStrategies(ExchangeStrategies.builder()
        .codecs(clientCodecConfigurer -> clientCodecConfigurer
            .defaultCodecs()
            .maxInMemorySize(16 * 1024 * 1024))
        .build())
    .build();

¿Existe alguna posibilidad de realizar límites de velocidad dentro del propio WebClient?

He visto algunas respuestas que indican que puedo hacer límites de velocidad al realizar la solicitud. Preferiría definirlo dentro del WebClient, ya que el mismo WebClient se utiliza para diferentes solicitudes, por lo que necesito establecer un límite de velocidad general para este WebClient.

Por “límite de velocidad” me refiero a cuántas solicitudes puede enviar este WebClient por segundo. Por ejemplo, quiero limitar este WebClient a enviar solo 5 solicitudes por segundo.

Si esto no es posible utilizando el WebClient, ¿existen alternativas que tengan sentido?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible aplicar la limitación de velocidad dentro del propio WebClient. Spring WebFlux proporciona un operador RateLimiter que se puede utilizar para limitar la velocidad de las solicitudes realizadas por el WebClient.

    Para utilizar el operador RateLimiter, primero debes crear una instancia de RateLimiter, especificando el límite de velocidad deseado. Por ejemplo, para limitar el WebClient a 5 solicitudes por segundo:

    RateLimiter rateLimiter = RateLimiter.create(5);
    

    Luego, aplicas el operador al flujo de solicitudes del WebClient utilizando el operador transform:

    WebClient webClient = WebClient.builder()
       .exchangeStrategies(ExchangeStrategies.builder()
          .codecs(clientCodecConfigurer -> clientCodecConfigurer
               .defaultCodecs()
               .maxInMemorySize(16 * 1024 * 1024))
          .build())
       .filter(ExchangeFilterFunctions
          .basicAuthentication(username, password))
       .filter(ExchangeFilterFunctions
          .fromRequestProcessor(request -> Mono.just(request)
               .transform(decorateRequestWithRateLimiter(rateLimiter))))
       .build();
    
    private static Function<><clientrequest>, Mono<clientrequest>> decorateRequestWithRateLimiter(RateLimiter rateLimiter) {
       return requestMono -> Mono.fromCallable(rateLimiter::acquire)
               .then(requestMono);
    }
    

    En el ejemplo anterior, utilizamos el operador fromRequestProcessor para aplicar una función de limitación de velocidad a cada solicitud realizada por el WebClient. La función decorateRequestWithRateLimiter toma un Mono de la solicitud actual y devuelve un nuevo Mono que espera un token del limitador de velocidad antes de continuar con la solicitud original.

    Ten en cuenta que el operador filter se puede utilizar para aplicar varias funciones al flujo de solicitudes. En el ejemplo anterior, también hemos agregado dos ExchangeFilterFunctions para autenticar la solicitud.

    Si estás utilizando Spring Boot, otra opción es utilizar Spring Cloud Gateway con una ruta que aproveche el filtro de limitación de velocidad. Sin embargo, este enfoque sería un poco exagerado si solo necesitas configurar esta limitación por cliente en lugar de para un grupo de clientes.

Comments are closed.