Heim  >  Artikel  >  Datenbank  >  Wie implementiert Redis die Strombegrenzung? Einführung in 3 Implementierungsmethoden

Wie implementiert Redis die Strombegrenzung? Einführung in 3 Implementierungsmethoden

青灯夜游
青灯夜游nach vorne
2020-07-21 17:06:284160Durchsuche

Wie implementiert Redis die Strombegrenzung? Einführung in 3 Implementierungsmethoden

Der erste: Redis-basierte Setnx-Operation

Wenn wir die verteilte Sperre von Redis verwenden, wie wir alle wissen, Es basiert auf dem Befehl „setnx“ (Vergleichen und Tauschen), um die Ablaufdauer (expire) für den angegebenen Schlüssel festzulegen von Anfragen, die auf mein Codeprogramm zugreifen können. 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 Setnx 20 erreicht, wird der aktuelle Begrenzungseffekt erreicht. Der Code ist relativ einfach und wird nicht angezeigt.

Dieser Ansatz hat natürlich viele Nachteile. Wenn Sie beispielsweise 1–10 Sekunden zählen, ist es unmöglich, 2–11 Sekunden zu zählen Redis muss N-Schlüssel und andere Probleme verwalten

Der zweite Typ: Redis-basierte Datenstruktur zset

Tatsächlich ist das Wichtigste bei der Strombegrenzung die Schiebefenster, wie oben. Es wurde auch erwähnt, wie aus 1-10 2-11 wird. Tatsächlich sind sowohl der Startwert als auch der Endwert jeweils +1.

Wenn wir die Listendatenstruktur von Redis verwenden, können wir diese Funktion einfach implementieren.

Wir können die Anfrage in ein Zset-Array einbauen. Wenn jede Anfrage eingeht, bleibt der Wert eindeutig mit UUID, und der Score kann durch den aktuellen Zeitstempel dargestellt werden, da der Score zur Berechnung der Anzahl der Anfragen innerhalb des aktuellen Zeitstempels verwendet werden kann. Die zset-Datenstruktur stellt auch die Range-Methode bereit, sodass wir problemlos die Anzahl der Anforderungen innerhalb von 2 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("访问成功");
 }

Der obige Code kann den Effekt eines Schiebefensters erzielen und kann höchstens M Anfragen alle N Sekunden garantieren. Der Nachteil besteht darin, dass die Datenstruktur von zset immer größer wird. Die Implementierungsmethode ist relativ einfach.

Dritter Typ: Redis-basierter Token-Bucket-Algorithmus

Wenn es um die Strombegrenzung geht, müssen wir den Token-Bucket-Algorithmus erwähnen. Der Token-Bucket-Algorithmus wird auch Bucket-Algorithmus genannt. Weitere Informationen finden Sie in Du Niangs Erklärung zum Token-Bucket-Algorithmus.

Der Token-Bucket-Algorithmus erwähnt die Eingaberate und die Ausgaberate als die Eingangsrate, dann ist das Traffic-Limit ü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 wurde wird das Gegenteil sein.

Auf der Grundlage der oben genannten Ideen können wir die Listendatenstruktur von Redis kombinieren, um auf einfache Weise einen solchen Code zu erreichen.

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

Verlassen Sie sich Die geplante Aufgabe von Java besteht darin, das Token regelmäßig in die Liste zu verschieben. Natürlich muss das Token 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 es nicht schwierig, das zu implementieren Code am Anfang Für diese aktuellen Begrenzungsmethoden können wir den oben genannten Code zu AOP oder Filter hinzufügen, um den aktuellen 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 Redis-Kenntnisse finden Sie in der Spalte Redis-Einführungs-Tutorial.

Das obige ist der detaillierte Inhalt vonWie implementiert Redis die Strombegrenzung? Einführung in 3 Implementierungsmethoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen