[JAVA] Ratenbegrenzung mit Guavas RateLimiter

https://github.com/google/guava

Guave wird von Google als OSS bereitgestellt und bietet verschiedene Kernprozesse, die Java als Bibliothek benötigt. Es enthält eine Klasse namens RateLimiter für die Verarbeitung zur Ratenbegrenzung. Verwenden wir sie also einfach.

Sample --PERMITS_PER_SECONDS: Anzahl der Prozesse, die gleichzeitig verarbeitet werden können --PERMITS_CONSUMED: Anzahl der in einem Prozess verbrauchten Prozesse (ändern Sie diesen Wert, wenn Sie das Gewicht eines Prozesses ändern möchten) --RateLimiter # tryAcquire: Eine Methode, die testet, ob das übergebene PERMITS_CONSUMED verwendet werden kann. Das zweite Argument ist der Timeout-Wert. Gibt true zurück, wenn es durch das Timeout erhalten werden kann, andernfalls false.

Wenn Sie versuchen, mit dem Controller of Spring Boot mithilfe des Mechanismus eine Ratenbegrenzung zu realisieren, ist dies wie folgt.

@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));
        }};
    }
}

Durch die Verwendung von RateLimter zur ausschließlichen Steuerung der Anzahl gleichzeitiger Prozesse auf die oben beschriebene Weise kann eine einfache Verarbeitung zur Ratenbegrenzung implementiert werden.

Running

Normale Zeit (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"}

Bei Ratenbegrenzung (500 werden bei der Implementierung zurückgegeben)

< 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 Sie können die naive Rete-Limiting-Verarbeitung wie oben mit dem RateLimiter von Guava schreiben.

Die Ratenbegrenzung muss jedoch bei der Implementierung und beim Betrieb viele Aspekte berücksichtigen, sodass es möglicherweise nicht sehr realistisch ist, sie von Grund auf neu zu implementieren.

Armeria ist ein Web Framework, das RateLimter verwendet, um weltweit Ratenbegrenzungen für OSS durchzuführen.

https://github.com/line/armeria

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

Mit Armeria können Sie die Drosselungsverarbeitung (Ratenbegrenzung) mit Decorator definieren, was anscheinend einfach einzuführen ist. Ich denke, eine Möglichkeit besteht darin, eine Webanwendung mit diesen OSS zu entwickeln.

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

Armeria unterstützt auch Bucket4j-basiertes (Token Bucket-basiertes) Throttling.

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

Recommended Posts

Ratenbegrenzung mit Guavas RateLimiter
Ratenbegrenzung mit RateLimiter of Resilience4j