redis-util: Nginx-module-lua-resty-redis обертка утилит
Установка
Если вы еще не настроили подписку на RPM-репозиторий, зарегистрируйтесь. Затем вы можете продолжить с следующими шагами.
CentOS/RHEL 7 или 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
Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что установлен nginx-module-lua.
Этот документ описывает lua-resty-redis-util v0.7, выпущенный 15 декабря 2021 года.
Введение
Этот проект основан на [openresty/lua-resty-redis][] и является библиотекой для работы с Redis, разработанной [章亦春(agentzh)][agentzh] в openresty. Это утилита для вторичной обертки. Основные функции по-прежнему выполняются [openresty/lua-resty-redis][].
В этом документе предполагается, что вы уже знакомы с использованием lua-скриптов в nginx+lua или openresty (например, конфигурация lua_package_path, *_by_lua_file), основными знаниями о Redis и базовыми методами использования [openresty/lua-resty-redis][] ([openresty/lua-resty-redis#README.md][README.md]).
Установка
opm get anjia0532/lua-resty-redis-util
Сравнение
Приведем часть официального кода для объяснения
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) -- 1 сек -- установка времени ожидания
local ok, err = red:connect("127.0.0.1", 6379) -- установка хоста и порта Redis
if not ok then -- проверка на успешность подключения
ngx.say("не удалось подключиться: ", err)
return
end
ok, err = red:set("dog", "an animal") -- вставка ключа (аналог mysql insert)
if not ok then -- проверка на успешность операции
ngx.say("не удалось установить dog: ", err)
return
end
ngx.say("результат установки: ", ok) -- вывод результата на страницу
-- помещаем в пул соединений размером 100,
-- с максимальным временем простоя 10 секунд
local ok, err = red:set_keepalive(10000, 100) -- помещаем соединение в пул, 100 соединений, максимальное время простоя 10 секунд
if not ok then -- проверка на успешность помещения в пул
ngx.say("не удалось установить keepalive: ", err)
return
end
-- если не помещать в пул, а закрыть сразу после использования, используйте следующий код
-- или просто закройте соединение сразу:
-- local ok, err = red:close()
-- if not ok then
-- ngx.say("не удалось закрыть: ", err)
-- return
-- end
Если вы использовали Java, C# и другие объектно-ориентированные языки, вам может показаться, что такой подход слишком... требует рефакторинга, так как он раскрывает слишком много несущественных деталей, что приводит к большому количеству повторяющегося кода.
А теперь тот же самый контент, используя мой обернутый код. Скрыты операции по настройке пула соединений, получению соединений, возвращению соединений в пул и т.д.
-- Зависимая библиотека
local redis = require "resty.redis-util"
-- Инициализация
local red = redis:new();
-- Вставка ключа
local ok, err = red:set("dog", "an animal")
-- Проверка результата
if not ok then
ngx.say("не удалось установить dog:", err)
return
end
-- Вывод результата на страницу
ngx.say("результат установки: ", ok) -- вывод результата на страницу
Важные моменты
Значения по умолчанию
local red = redis:new();
-- использованы значения по умолчанию, эквивалентно
local red2 = redis:new({
host='127.0.0.1',
port=6379,
db_index=0,
password=nil,
timeout=1000,
keepalive=60000,
pool_size=100
});
- host: хост Redis, по умолчанию: 127.0.0.1
- port: порт Redis, по умолчанию: 6379
- db_index: индекс базы данных Redis (по умолчанию 0-15, всего 16 баз), по умолчанию используется база 0 (рекомендуется использовать разные порты для разных экземпляров или разные префиксы, так как для смены базы необходимо использовать команду select), по умолчанию: 0
- password: пароль для аутентификации Redis
- timeout: время ожидания подключения к Redis, по умолчанию: 1000 (1 секунда)
- keepalive: максимальное время простоя пула соединений Redis, по умолчанию: 60000 (1 минута)
- pool_size: размер пула соединений Redis, по умолчанию: 100
subscribe
Поскольку pub/sub не используется, реализованы только простые (un)subscribe, без дальнейшей реализации (un)psubscribe (подписка по шаблону), см. [Вторичная обертка интерфейса Redis (публикация и подписка)][linkRedis接口的二次封装(发布订阅)]
local cjson = require "cjson"
local red = redis:new();
-- Подписка на канал dog
local func = red:subscribe( "dog" )
-- Проверка успешности подписки
if not func then
return nil
end
-- Получение значения
local res, err = func() -- func()=func(true)
-- Если не удалось, отменяем подписку
if err then
func(false)
end
-- Если получили результат, выводим на страницу
if res then
ngx.say("1: получено: ", cjson.encode(res))
end
-- Получаем снова
res, err = func()
-- После успешного получения, отменяем подписку func(false)
if res then
ngx.say("2: получено: ", cjson.encode(res))
func(false)
end
pipeline
См. [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("не удалось выполнить запрашиваемые операции в пайплайне: ", err)
return
else
ngx.say("pipeline", cjson.encode(results))
end
-- вывод pipeline["OK","OK","Marry","Bob"]
script
См. [скрипт сжатия сложных запросов][linkScript压缩复杂请求]
local red = redis:new();
local id = 1
local res, err = red:eval([[
-- Обратите внимание, что при выполнении скрипта в Redis, значения, извлекаемые из KEYS/ARGV, имеют тип 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("не удалось получить информацию о группе: ", err)
return
end
ngx.say("скрипт", res)
Благодарности
Этот инструмент заимствован из [lua-resty-redis/lib/resty/redis.lua][] и кода [Вторичной обертки интерфейса Redis][linkRedis接口的二次封装].
Обратная связь
Если у вас есть вопросы, пожалуйста, создайте [issues][].
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-redis-util.