public class Throttler
extends java.lang.Object
Klasse zum Ausbremsen von Login-Versuchen und ähnlichem. Je häufiger die Methode trigger() (pro Minute) aufgerufen wird, desto länger blockiert die Methode.
Wird der Thread mit Thread.interrupt()
unterbrochen, beendet sich das Warten sofort
Modifier and Type | Field and Description |
---|---|
private java.util.concurrent.locks.ReentrantLock |
_lock
Lock-Objekt zur Synchronisation
|
private java.time.Duration |
_maxThrottleDuration
Maximale Wartezeit innerhalb der
trigger() -methode (bei Verwendung von nur einem Thread) |
private java.time.Duration |
_slidingWindowLength
Länge des Sliding Window
|
private java.time.Duration |
_throttlePerCall
Wartezeit pro vorhergehendem Methodenaufruf von
trigger() |
private java.util.PriorityQueue<java.time.Instant> |
_timeStamps
Liste mit Zeitstempeln von vorherigen Login-Versuchen
|
Constructor and Description |
---|
Throttler(java.time.Duration throttlePerCall,
java.time.Duration maxThrottleDuration)
Erstellt eine neuen Throttler zum Ausbremsen von häufigen Methodenaufrufen (z.
|
Modifier and Type | Method and Description |
---|---|
private void |
cleanQueue(java.time.Instant instant)
Entfernt alle Einträge, die älter sind als der aktuelle Zeitstempel, aus der Queue
|
protected long |
delayMillisFor(int numLoginAttempts)
Berechnet die Wartezeit aus der anzahl der vorherigen Login-Versuche
|
java.time.Duration |
getMaxThrottleDuration()
Gibt die maximale Wartezeit bei Verwendung eines einzelnen Threads zurück
|
java.time.Duration |
getSlidingWindowLength()
Gibt die Länge des Sliding Window zurück.
|
java.time.Duration |
getThrottlePerCall()
Gibt die Wartezeit pro Methodenaufruf zurück
|
void |
trigger()
Methode, deren Ausführung länger dauert, je öfter sie pro Zeitbereich aufgerufen wird.
|
void |
trigger(boolean addToQueue)
Methode, deren Ausführung länger dauert, je öfter sie pro Zeitbereich aufgerufen wird.
|
private final java.util.PriorityQueue<java.time.Instant> _timeStamps
Liste mit Zeitstempeln von vorherigen Login-Versuchen
private final java.time.Duration _slidingWindowLength
Länge des Sliding Window
private final java.time.Duration _throttlePerCall
Wartezeit pro vorhergehendem Methodenaufruf von trigger()
private final java.time.Duration _maxThrottleDuration
Maximale Wartezeit innerhalb der trigger()
-methode (bei Verwendung von nur einem Thread)
private final java.util.concurrent.locks.ReentrantLock _lock
Lock-Objekt zur Synchronisation
public Throttler(java.time.Duration throttlePerCall, java.time.Duration maxThrottleDuration)
Erstellt eine neuen Throttler zum Ausbremsen von häufigen Methodenaufrufen (z. B. Login-Versuchen).
Die Methode trigger()
dieser Klasse ist die wesentliche Methode. Je öfter sie aufgerufen wird, desto länger dauert es, bis die Methode wieder verlassen wird.
Diese Klasse besitzt 2 Parameter:
throttlePerCall
gibt eine Zeitdauer an, die pro Login-Versuch in letzter Zeit gewartet wird. gibt es keinen Login-Versuch in letzter Zeit wird die Methode sofort verlassen.
maxThrottleDuration
gibt die maximale Wartezeit an, die ein Thread ausgebremst wird. Da immer nur ein Thread gleichzeitig warten kann, kann es bei mehreren parallelen Aufrufen der trigger()
-Methode zu entsprechend längeren Wartezeiten kommen (Anzahl Threads * maxThrottleDuration
)
Die Zeitdauer (Sliding Window), in der vorhergehende Methodenaufrufe zur Bestimmung der Wartedauer berücksichtigt werden, ergibt sich aus maxThrottleDuration * (maxThrottleDuration / throttlePerCall)
. Das heißt, das gerade so viele Methodenaufrufe gemerkt werden, wie zum dauerhaften Beibehalten der maxThrottleDuration
notwendig ist. Beispiel: maxThrottleDuration = 5 Sekunden, throttlePerCall = 1 Sekunde, dann müssen mindestens die letzten 5 * (5 / 1) = 25 Sekunden berücksichtigt werden, um bei dauerhaften Login-Versuchen eine konstante Wartezeit von 5 Sekunden beizubehalten.
throttlePerCall
- Zeitdauer, die pro Login-Versuch in letzter Zeit gewartet wirdmaxThrottleDuration
- maximale Wartezeit, die ein Thread ausgebremst wirdpublic void trigger()
Methode, deren Ausführung länger dauert, je öfter sie pro Zeitbereich aufgerufen wird. Der Aufruf der Methode dauert throttlePerCall
for jeden vorhergehenden Methodenaufruf innerhalb des Sliding Windows. Die Wartezeit ist maximal maxThrottleDuration
, kann allerdings bei parallelen Aufrufen aus mehreren Threads noch länger sein, da sich nur ein Thread gleichzeitig in der Methode befinden darf. (Sonst könnte man das Warten umgehen indem man mehrere Threads gleichzeitig startet bzw. durch mehrere Verbindungen mehrere Threads erzeugt usw.)
public void trigger(boolean addToQueue)
Methode, deren Ausführung länger dauert, je öfter sie pro Zeitbereich aufgerufen wird. Siehe trigger()
.
addToQueue
- Soll dieser Methodenaufruf dafür sorgen, dass folgende Aufrufe länger dauern (true
ist standard, falls false
wird nur gewartet)protected long delayMillisFor(int numLoginAttempts)
Berechnet die Wartezeit aus der anzahl der vorherigen Login-Versuche
numLoginAttempts
- Anzahl Login-Versucheprivate void cleanQueue(java.time.Instant instant)
Entfernt alle Einträge, die älter sind als der aktuelle Zeitstempel, aus der Queue
instant
- Zeitstempelpublic java.time.Duration getSlidingWindowLength()
Gibt die Länge des Sliding Window zurück.
Die Zeitdauer (Sliding Window), in der vorhergehende Methodenaufrufe zur Bestimmung der Wartedauer berücksichtigt werden, ergibt sich aus maxThrottleDuration * (maxThrottleDuration / throttlePerCall)
. Das heißt, das gerade so viele Methodenaufrufe gemerkt werden, wie zum dauerhaften Beibehalten der maxThrottleDuration
notwendig ist. Beispiel: maxThrottleDuration = 5 Sekunden, throttlePerCall = 1 Sekunde, dann müssen mindestens die letzten 5 * (5 / 1) = 25 Sekunden berücksichtigt werden, um bei dauerhaften Login-Versuchen eine konstante Wartezeit von 5 Sekunden beizubehalten.
public java.time.Duration getThrottlePerCall()
Gibt die Wartezeit pro Methodenaufruf zurück
public java.time.Duration getMaxThrottleDuration()
Gibt die maximale Wartezeit bei Verwendung eines einzelnen Threads zurück