Heim  >  Artikel  >  Datenbank  >  Wie viele Möglichkeiten gibt es, die Redis-Strombegrenzung zu implementieren?

Wie viele Möglichkeiten gibt es, die Redis-Strombegrenzung zu implementieren?

coldplay.xixi
coldplay.xixiOriginal
2020-06-30 13:28:003262Durchsuche

Es gibt drei Möglichkeiten, die Redis-Strombegrenzung zu implementieren, nämlich: 1. Basierend auf der Setnx-Operation von Redis wird die Ablaufpraxis für den angegebenen Schlüssel festgelegt. 2. Basierend auf der Redis-Datenstruktur zset, der Anforderung wird in ein zset-Array umgewandelt. 3. Token-Bucket-Algorithmus basierend auf Redis. Wenn die Ausgaberate größer als die Eingaberate ist, muss der Strom begrenzt werden.

Wie viele Möglichkeiten gibt es, die Redis-Strombegrenzung zu implementieren?

Es gibt drei Möglichkeiten, die Redis-Strombegrenzung zu implementieren, nämlich:

Die erste: Redis -basierte setnx-Operation

Wenn wir die verteilte Sperre von Redis verwenden, weiß jeder, dass wir uns auf die setnx-Anweisung verlassen. Während der CAS-Operation (Vergleichen und Tauschen) geben wir auch an, dass der angegebene Schlüssel abläuft 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 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 behalten und andere Probleme

Verwandte Lernempfehlungen: Redis-Video-Tutorial

Zweiter Typ: Redis-basierte Daten Struktur zset

Tatsächlich ist das Schiebefenster das Wichtigste bei der Strombegrenzung. 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 einbauen. Wenn jede Anfrage eingeht, bleibt der Wert eindeutig. Wird mit UUID generiert 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 von Schiebefenstern 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 der Erklärung von Du Niang. Token-Bucket-Algorithmus

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

Basierend auf den oben genannten Ideen können wir die List-Datenstruktur von Redis kombinieren, um solchen Code einfach zu implementieren.

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 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 lässt sich sagen, dass die Implementierung nicht schwierig ist 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).

Wenn Sie Fragen haben, hinterlassen Sie bitte eine Nachricht

Das obige ist der detaillierte Inhalt vonWie viele Möglichkeiten gibt es, die Redis-Strombegrenzung zu implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn