Aller au contenu

redis-util: Outil de classe encapsulant nginx-module-lua-resty-redis

Installation

Si vous n'avez pas encore configuré l'abonnement au dépôt RPM, inscrivez-vous. Ensuite, vous pouvez procéder avec les étapes suivantes.

CentOS/RHEL 7 ou Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-redis-util

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-redis-util

Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.

Ce document décrit lua-resty-redis-util v0.7 publié le 15 décembre 2021.


Introduction

Ce projet est basé sur [openresty/lua-resty-redis][] développé par [章亦春(agentzh)][agentzh], une bibliothèque pour manipuler Redis dans OpenResty. C'est une bibliothèque d'outils pour une encapsulation secondaire. Les fonctionnalités principales sont toujours réalisées par [openresty/lua-resty-redis][].

Cet article suppose que vous avez déjà une compréhension de nginx+lua ou d'OpenResty sur l'utilisation de scripts Lua (par exemple, configuration lua_package_path, *_by_lua_file), des connaissances de base sur Redis, ainsi que sur l'utilisation de base de [openresty/lua-resty-redis][] ([openresty/lua-resty-redis#README.md][README.md]).

Installation

opm get anjia0532/lua-resty-redis-util

Comparaison

Extrait de la partie officielle du code pour explication

    local redis = require "resty.redis"
    local red = redis:new()

    red:set_timeout(1000) -- 1 sec -- définit le temps d'attente

    local ok, err = red:connect("127.0.0.1", 6379) -- définit l'hôte et le port de Redis
    if not ok then -- vérifie si la connexion a échoué
        ngx.say("échec de la connexion : ", err)
        return
    end

    ok, err = red:set("dog", "un animal") -- insère la clé (similaire à l'insertion MySQL)
    if not ok then -- vérifie si l'opération a réussi
        ngx.say("échec de la définition du chien : ", err)
        return
    end

    ngx.say("résultat de la définition : ", ok) -- affiche le résultat
    -- le mettre dans le pool de connexions de taille 100,
    -- avec un temps d'inactivité maximum de 10 secondes
    local ok, err = red:set_keepalive(10000, 100) -- met la connexion dans le pool de connexions, 100 connexions, temps d'inactivité maximum de 10 secondes
    if not ok then -- vérifie le résultat de la mise dans le pool
        ngx.say("échec de la définition de keepalive : ", err)
        return
    end
    -- Si vous ne mettez pas dans le pool, fermez simplement après utilisation, utilisez l'écriture suivante
    -- ou fermez simplement la connexion immédiatement :
    -- local ok, err = red:close()
    -- if not ok then
    --     ngx.say("échec de la fermeture : ", err)
    --     return
    -- end

Si vous avez utilisé Java, C# ou d'autres langages orientés objet, vous trouverez que cette écriture est trop... il faut absolument refactoriser, cela expose trop de détails non pertinents, entraînant une grande quantité de code répétitif.

Le même contenu, en utilisant mon code encapsulé. Cela cache les opérations de configuration du pool de connexions, de récupération de connexions, et de retour des connexions au pool.

    -- bibliothèque dépendante
    local redis = require "resty.redis-util"
    -- initialisation
    local red = redis:new();
    -- insertion de la clé
    local ok, err = red:set("dog", "un animal")
    -- vérification du résultat
    if not ok then
      ngx.say("échec de la définition du chien :", err)
      return
    end
    -- affichage du résultat
    ngx.say("résultat de la définition : ", ok) -- affiche le résultat

Remarques

Valeurs par défaut

local red = redis:new();
-- utilise les valeurs par défaut, équivalent à
local red2 = redis:new({
                            host='127.0.0.1',
                            port=6379,
                            db_index=0,
                            password=nil,
                            timeout=1000,
                            keepalive=60000,
                            pool_size=100
                        });
  • host : hôte Redis, par défaut : 127.0.0.1
  • port : port Redis, par défaut : 6379
  • db_index : index de la base de données Redis (par défaut 0-15, soit 16 bases de données), la base par défaut est la base 0 (il est conseillé d'ouvrir différentes instances sur différents ports ou d'utiliser différents préfixes, car le changement de base nécessite la commande select), par défaut : 0
  • password : mot de passe d'authentification Redis
  • timeout : temps d'attente de connexion Redis, par défaut : 1000 (1s)
  • keepalive : temps d'inactivité maximum du pool de connexions Redis, par défaut : 60000 (1m)
  • pool_size : taille du pool de connexions Redis, par défaut : 100

subscribe

Comme la fonction pub/sub n'est pas utilisée, seule une simple implémentation de (un)subscribe a été réalisée, sans implémentation de (un)psubscribe (abonnement par motif), voir [Redis 接口的二次封装(发布订阅)][linkRedis接口的二次封装(发布订阅)]

    local cjson = require "cjson"
    local red = redis:new();

    -- s'abonner au canal dog
    local func  = red:subscribe( "dog" )

    -- vérifie si l'abonnement a réussi
    if not func then
      return nil
    end

    -- obtenir la valeur
    local res, err = func() -- func()=func(true)
    -- si cela échoue, annulez l'abonnement
    if err then
        func(false)
    end

    -- si un résultat est obtenu, afficher sur la page
    if res then
        ngx.say("1 : reçu : ", cjson.encode(res))
    end

    -- obtenir à nouveau
    res, err = func()

    -- après avoir réussi à obtenir, annulez l'abonnement func(false)
    if res then
        ngx.say("2 : reçu : ", cjson.encode(res))
        func(false)
    end

pipeline

Voir [openresty/lua-resty-redis#Synopsis][]

    local cjson = require "cjson"
    local red = redis:new();

    red:init_pipeline()

    red:set("cat", "Marry")
    red:set("horse", "Bob")
    red:get("cat")
    red:get("horse")

    local results, err = red:commit_pipeline()

    if not results then
        ngx.say("échec de l'engagement des requêtes en pipeline : ", err)
        return
    else
        ngx.say("pipeline", cjson.encode(results))
    end
    -- sortie pipeline["OK","OK","Marry","Bob"]

script

Voir [script 压缩复杂请求][linkScript压缩复杂请求]

    local red = redis:new();

    local id = 1
    local res, err = red:eval([[
        -- Notez qu'en exécutant des scripts dans Redis, les valeurs extraites de KEYS/ARGV sont de type string
        local info = redis.call('get', KEYS[1])
        info = cjson.decode(info)
        local g_id = info.gid

        local g_info = redis.call('get', g_id)
        return g_info
        ]], 1, id)

    if not res then
       ngx.say("échec de l'obtention des informations du groupe : ", err)
       return
    end

    ngx.say("script", res)

Remerciements

Cet outil s'inspire du code de [lua-resty-redis/lib/resty/redis.lua][] et de [Redis 接口的二次封装][linkRedis接口的二次封装].

Retours

Si vous avez des questions, n'hésitez pas à soumettre des [issues][].

GitHub

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-redis-util.