Heim  >  Artikel  >  Backend-Entwicklung  >  So verwenden Sie Redis, um eine Verzögerungswarteschlange in Golang zu implementieren.

So verwenden Sie Redis, um eine Verzögerungswarteschlange in Golang zu implementieren.

PHPz
PHPzOriginal
2023-06-20 09:37:521604Durchsuche

So verwenden Sie Redis, um eine Verzögerungswarteschlange in Golang zu implementieren. Die Verzögerungswarteschlange ist eine sehr praktische Methode zur Nachrichtenverarbeitung. Sie verzögert die Nachricht für einen bestimmten Zeitraum, bevor sie verarbeitet wird. Sie wird im Allgemeinen zum Implementieren von Funktionen wie der Aufgabenplanung und geplanten Aufgaben verwendet. In der tatsächlichen Entwicklung ist Redis eine sehr häufig verwendete Cache-Datenbank. Sie bietet ähnliche Funktionen wie Nachrichtenwarteschlangen, sodass wir Redis zum Implementieren von Verzögerungswarteschlangen verwenden können. In diesem Artikel wird erläutert, wie Sie mit Golang und Redis eine Verzögerungswarteschlange implementieren.

ZSET von Redis
  1. Redis stellt die Datenstruktur sortierter Mengen (geordnete Mengen) bereit, mit denen wir eine Verzögerungswarteschlange implementieren können. In sortierten Mengen verfügt jedes Element über ein Score-Attribut, das zur Angabe der Gewichtung des Elements verwendet wird. Sortierte Sets speichern Elemente in aufsteigender Reihenfolge der Punktzahl. Elemente mit derselben Punktzahl werden nach ihren Mitgliedern sortiert. Wir können jede Aufgabe in ein Element kapseln und die Zeit, die zur Ausführung der Aufgabe benötigt wird, als Bewertung des Elements verwenden.

Implementierung der Verzögerungswarteschlange
  1. Konkret können wir den ZADD-Befehl von Redis verwenden, um Aufgaben zur Verzögerungswarteschlange hinzuzufügen. Zum Beispiel:
//添加任务到延迟队列
func AddTaskToDelayQueue(taskId string, delayTime int64) error {
    _, err := redisClient.ZAdd("DelayedQueue", redis.Z{
        Score:  float64(time.Now().Unix() + delayTime),
        Member: taskId,
    }).Result()
    if err != nil {
        return err
    }
    return nil
}

Im obigen Code haben wir den ZADD-Befehl von Redis verwendet, um dem sortierten Satz eine Aufgabe mit dem Namen „DelayedQueue“ hinzuzufügen. Darunter gibt Verzögerungszeit die Zeit an, die die Aufgabe verschoben werden muss, und Score ist die aktuelle Zeit plus Verzögerungszeit, also der Zeitstempel, zu dem die Aufgabe ausgeführt werden muss.

In tatsächlichen Geschäftsszenarien können wir vor der Aufgabenausführung das Element mit der kleinsten Punktzahl in der Verzögerungswarteschlange abrufen, d. h. die letzte Aufgabe, die ausgeführt werden muss:

//获取延迟任务队列中最近需要执行的任务id
func GetNextTaskFromDelayQueue() (string, error) {
    now := time.Now().Unix()
    items, err := redisClient.ZRangeByScore("DelayedQueue", redis.ZRangeBy{
        Min:    "-inf",
        Max:    strconv.FormatInt(now, 10),
        Offset: 0,
        Count:  1,
    }).Result()
    if err != nil {
        return "", err
    }
    if len(items) == 0 {
        return "", nil
    }
    return items[0], nil
}

Im obigen Code verwenden wir den Befehl ZRangeByScore von Redis, um die Verzögerungswarteschlange zu erhalten Das Element, dessen Punktzahl kleiner oder gleich dem aktuellen Zeitstempel ist, verwendet dann das erste Element in der Liste als nächste auszuführende Aufgabe.

Verarbeitung nach der Aufgabenausführung
  1. Nachdem wir die Aufgaben, die ausgeführt werden müssen, aus der Verzögerungswarteschlange erhalten haben, können wir die Aufgaben aus der Liste der auszuführenden Aufgaben in die Liste der ausgeführten Aufgaben verschieben, damit wir die Ausführung zählen können die Aufgaben.
//将已经执行的任务移除
func RemoveTaskFromDelayQueue(taskId string) error {
    _, err := redisClient.ZRem("DelayedQueue", taskId).Result()
    if err != nil {
        return err
    }
    return nil
}

Vollständiges Codebeispiel
  1. Wir haben den obigen Code zusammengestellt und einige Fehlerbehandlungs- und Protokollinformationen hinzugefügt, um ein vollständiges Codebeispiel zu erhalten:
package delayqueue

import (
    "strconv"
    "time"

    "github.com/go-redis/redis"
)

var redisClient *redis.Client

//初始化redis连接
func InitRedis(redisAddr string, redisPassword string) error {
    redisClient = redis.NewClient(&redis.Options{
        Addr:     redisAddr,
        Password: redisPassword,
        DB:       0,
    })

    _, err := redisClient.Ping().Result()
    if err != nil {
        return err
    }
    return nil
}

//添加任务到延迟队列
func AddTaskToDelayQueue(taskId string, delayTime int64) error {
    _, err := redisClient.ZAdd("DelayedQueue", redis.Z{
        Score:  float64(time.Now().Unix() + delayTime),
        Member: taskId,
    }).Result()
    if err != nil {
        return err
    }
    return nil
}

//获取延迟任务队列中最近需要执行的任务id
func GetNextTaskFromDelayQueue() (string, error) {
    now := time.Now().Unix()
    items, err := redisClient.ZRangeByScore("DelayedQueue", redis.ZRangeBy{
        Min:    "-inf",
        Max:    strconv.FormatInt(now, 10),
        Offset: 0,
        Count:  1,
    }).Result()
    if err != nil {
        return "", err
    }
    if len(items) == 0 {
        return "", nil
    }
    return items[0], nil
}

//将已经执行的任务移除
func RemoveTaskFromDelayQueue(taskId string) error {
    _, err := redisClient.ZRem("DelayedQueue", taskId).Result()
    if err != nil {
        return err
    }
    return nil
}

Zusammenfassung
  1. Dieser Artikel stellt vor, wie man Golang und Redis implementiert eine Verzögerungswarteschlange. Durch die Verwendung der ZSET-Datenstruktur können wir problemlos eine Verzögerungswarteschlange implementieren, was in der tatsächlichen Entwicklung sehr praktisch ist. Neben Verzögerungswarteschlangen bietet Redis auch viele andere Datenstrukturen und Funktionen, die es wert sind, erkundet und genutzt zu werden.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Redis, um eine Verzögerungswarteschlange in Golang 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