In diesem Artikel werden Ihnen drei Möglichkeiten zur Implementierung der Strombegrenzung in Redis vorgestellt. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.
【Verwandte Empfehlung: Redis-Video-Tutorial】
Angesichts immer mehr Szenarien mit hoher Parallelität ist die Anzeige des aktuellen Limits besonders wichtig.
Natürlich gibt es viele Möglichkeiten, die Strombegrenzung zu implementieren. Ich habe Redis verwendet, um drei Implementierungsmethoden zu üben, die auf relativ einfache Weise implementiert werden können. Redis kann nicht nur den Strom begrenzen, sondern auch Datenstatistiken, Personen in der Nähe und andere Funktionen erstellen, die möglicherweise später geschrieben werden.
Der erste: Setnx-Betrieb basierend auf Redis
Wenn wir verteilte Redis-Sperren verwenden, weiß jeder, dass wir uns bei CAS-Vorgängen (Vergleichen und Tauschen) auf die Setnx-Anweisungen verlassen und gleichzeitig einen Ablauf festlegen Übung (Ablauf) für den angegebenen Schlüssel. Unser Hauptzweck der Strombegrenzung besteht darin, nur N Anfragen den Zugriff auf mein Codeprogramm innerhalb einer Zeiteinheit zu ermöglichen. Wenn Sie sich also auf setnx verlassen, können Sie diese Funktion problemlos erreichen.
Wenn wir beispielsweise 20 Anfragen innerhalb von 10 Sekunden begrenzen müssen, können wir die Ablaufzeit auf 10 setzen, wenn die Anzahl der angeforderten SetsNX 20 erreicht, wird der aktuelle Begrenzungseffekt erreicht. Der Code ist relativ einfach und wird nicht angezeigt.
Informationen zur spezifischen Verwendung von setnx finden Sie in meinem anderen Blog. Eine Reihe von Problemen, die durch verteilte Redis-Sperren unter RedisTemplate verursacht werden.
Natürlich hat dieser Ansatz viele Nachteile, wenn man beispielsweise 1-10 Sekunden zählt, 2-. 11 kann nicht innerhalb von Sekunden gezählt werden. Wenn wir M Anfragen innerhalb von N Sekunden zählen müssen, müssen wir N Schlüssel und andere Probleme in Redis behalten
Zweitens: Redis-basierte Datenstruktur zset
Die Strombegrenzung beinhaltet Das Wichtigste ist das Schiebefenster. Oben wurde auch erwähnt, wie aus 1-10 2-11 wird. Tatsächlich sind sowohl der Startwert als auch der Endwert jeweils +1.
Und wenn wir die Listendatenstruktur von Redis verwenden, können wir diese Funktion einfach implementieren
Wir können die Anfrage in ein Zset-Array umwandeln. Wenn jede Anfrage eingeht, bleibt der Wert eindeutig und kann mit UUID generiert werden Der Score kann mit generiert werden Der aktuelle Zeitstempel stellt dar, denn mit dem Score können wir die Anzahl der Anfragen innerhalb des aktuellen Zeitstempels berechnen. Die zset-Datenstruktur stellt auch die Range-Methode bereit, sodass wir problemlos die Anzahl der Anforderungen innerhalb von zwei Zeitstempeln ermitteln können. Der Code lautet wie folgt:
public Response limitFlow(){ Long currentTime = new Date().getTime(); System.out.println(currentTime); if(redisTemplate.hasKey("limit")) { Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime - intervalTime, currentTime).size(); // intervalTime是限流的时间 System.out.println(count); if (count != null && count > 5) { return Response.ok("每分钟最多只能访问5次"); } } redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime); return Response.ok("访问成功"); }. Durch den obigen Code kann der Effekt des Schiebefensters erreicht werden, und zwar garantiert alle N Sekunden Bei den meisten M-Anfragen besteht der Nachteil darin, dass die Datenstruktur von zset immer größer wird. Die Implementierungsmethode ist relativ einfach.
Der Dritte: Redis-basierter Token-Bucket-Algorithmus
Wenn es um die Strombegrenzung geht, müssen wir den Token-Bucket-Algorithmus erwähnen. Einzelheiten finden Sie in Du Niangs Erklärung zum Token-Bucket-Algorithmus.
Der Token-Bucket-Algorithmus erwähnt die Eingaberate und die Ausgaberate. Wenn die Ausgaberate größer als die Eingaberate ist, wird das Verkehrslimit überschritten. Das heißt, jedes Mal, wenn wir auf eine Anfrage zugreifen, können wir ein Token von Redis erhalten. Wenn wir das Token erhalten, bedeutet dies, dass das Limit nicht überschritten wird, und wenn wir es nicht erhalten, ist das Ergebnis das Gegenteil .
Basierend auf den oben genannten Ideen können wir solchen Code einfach implementieren, indem wir die List-Datenstruktur von Redis kombinieren. Es ist nur eine einfache Implementierung.
Verlassen Sie sich auf den LeftPop von List, um das Token zu erhalten.
// 输出令牌 public Response limitFlow2(Long id){ Object result = redisTemplate.opsForList().leftPop("limit_list"); if(result == null){ return Response.ok("当前令牌桶中无令牌"); } return Response.ok(articleDescription2); }
Dann verlassen Sie sich auf die geplanten Aufgaben von Java Um regelmäßig zur Liste zu gelangen, muss das Push-Token natürlich auch eindeutig sein, daher verwende ich immer noch die UUID, um es zu generieren
// 10S的速率往令牌桶中添加UUID,只为保证唯一性 @Scheduled(fixedDelay = 10_000,initialDelay = 0) public void setIntervalTimeTask(){ redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString()); }
Zusammenfassend ist die Code-Implementierung am Anfang nicht schwierig. Für diese aktuellen Begrenzungsmethoden , wir können es in AOP hinzufügen oder filtern. Der obige Code wird verwendet, um den Fluss der Schnittstelle zu begrenzen und letztendlich Ihre Website zu schützen.
Redis hat tatsächlich viele andere Verwendungszwecke, nicht nur Caching und verteiltes Sperren. Seine Datenstrukturen sind nicht nur String, Hash, List, Set und Zset. Interessierte können die Struktur seines GeoHash-Algorithmus weiterverfolgen; BitMap-, HLL- und Bloom-Filterdaten (hinzugefügt nach Redis 4.0, Sie können Docker verwenden, um Redislabs/Rebloom direkt zu installieren).
Weitere Kenntnisse zum Thema Programmierung finden Sie unter:
Programmierlehre! !
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über drei Implementierungsmethoden der Redis-Strombegrenzung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!