[JAVA] Limitation de débit à l'aide de RateLimiter de goyave

https://github.com/google/guava

guava est fourni par google en tant que OSS et fournit divers processus de base requis par Java en tant que bibliothèque. Il contient une classe appelée RateLimiter pour le traitement de limitation de débit, alors utilisons-la facilement.

Sample --PERMITS_PER_SECONDS: nombre de processus pouvant être traités en même temps --PERMITS_CONSUMED: Nombre de processus consommés dans un processus (modifiez cette valeur si vous souhaitez modifier le poids d'un processus) --RateLimiter # tryAcquire: Une méthode qui teste si le PERMITS_CONSUMED passé peut être consommé. Le deuxième argument est la valeur du délai d'expiration. Renvoie true si elle peut être obtenue avant l'expiration du délai, false dans le cas contraire.

Si vous essayez de réaliser une limitation de débit avec le contrôleur de Spring Boot en utilisant le mécanisme, ce sera comme suit.

@Slf4j
@Controller
public class TestController {
    private static final Double PERMITS_PER_SECONDS = 1d;
    private static final int PERMITS_CONSUMED = 1;
 
    private AtomicInteger index = new AtomicInteger(0);
    private RateLimiter rateLimiter = RateLimiter.create(PERMITS_PER_SECONDS);
 
    @GetMapping("/hello")
    @ResponseBody
    public HashMap<String, String> sayHello() {
        final int id = index.incrementAndGet();
        final boolean acquired = rateLimiter.tryAcquire(PERMITS_CONSUMED, Duration.ofMillis(100L));
        if (!acquired) {
            throw new UncheckedIOException(new IOException("Rate Limit."));
        }
        log.debug("Serving request id " + id);
        return new HashMap<>() {{
            put("message", "Hello");
            put("id", String.valueOf(id));
            put("acquired", String.valueOf(acquired));
        }};
    }
}

En utilisant RateLimter pour contrôler exclusivement le nombre de processus simultanés de la manière ci-dessus, un traitement de limitation de débit simple peut être mis en œuvre.

Running

Heure normale (200)

< HTTP/1.1 200
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 20 Apr 2020 10:38:20 GMT
<
{ [60 bytes data]
 100    49    0    49    0     0  24500      0 --:--:-- --:--:-- --:--:-- 24500
* Connection #0 to host localhost left intact
{"id":"3092","message":"Hello","acquired":"true"}

At Rate-Limit (500 est retourné lors de la mise en œuvre)

< HTTP/1.1 500 
< Content-Type: application/json
< Transfer-Encoding: chunkedj
< Date: Mon, 20 Apr 2020 10:38:43 GMT
< Connection: close
< [
{ [5072 bytes data]
*100  5064    0  5064    0     0  2472k      0 --:--:-- --:--:-- --:--:-- 2472k
* Closing connection 0
{"timestamp":"2020-04-20T10:38:43.015+0000","status":500,"error":"Internal Server Error","message":"java.io.IOException: Rate Limit.","t
race":"java.io.UncheckedIOException: java.io.IOException: Rate Limit.  (snip.)

Appendix Vous pouvez écrire un traitement Naive Rete-Limiting comme ci-dessus en utilisant le RateLimiter de goyave.

Cependant, la limitation de débit a de nombreux aspects à prendre en compte lors de la mise en œuvre et de l'exploitation, de sorte qu'il n'est peut-être pas très réaliste de la mettre en œuvre à partir de zéro.

Armeria est un framework Web qui utilise RateLimter pour effectuer la limitation de débit sur OSS dans le monde.

https://github.com/line/armeria

https://github.com/line/armeria/blob/f03b400cff136a710dbdbeb75e0e4f741387d296/core/src/main/java/com/linecorp/armeria/server/throttling/RateLimitingThrottlingStrategy.java

Armeria vous permet de définir le traitement de Throttling (Rate-Limiting) avec Decorator, ce qui semble facile à introduire. Je pense qu'une façon est de développer une application Web en utilisant ces OSS.

https://image.slidesharecdn.com/2018-180227110721/95/building-asynchronous-microservices-with-armeria-24-638.jpg?cb=1519731604

Armeria prend également en charge la limitation basée sur bucket4j (Token Bucket).

https://github.com/line/armeria/blob/e8eecafb35bb7eb50f6cdd614b0b5d1faca8a308/bucket4j/src/main/java/com/linecorp/armeria/server/throttling/bucket4j/TokenBucketThrottlingStrategy.java

Recommended Posts

Limitation de débit à l'aide de RateLimiter de goyave
Limitation de débit à l'aide de RateLimiter of Resilience4j