lua-resty-redis-util

基于 openresty/lua-resty-redis,让操作 Redis 更轻松

$ opm get anjia0532/lua-resty-redis-util

介绍

本项目基于[openresty/lua-resty-redis][],它是[章亦春(agentzh)][agentzh]开发的 OpenResty 中操作 Redis 的库。本项目是对其进行二次封装的工具库。核心功能仍然由[openresty/lua-resty-redis][]完成。

本文假设您已经了解 Nginx+Lua 或者 OpenResty 如何使用 Lua 脚本(例如 lua_package_path 配置,*_by_lua_file),基础的 Redis 相关知识,以及[openresty/lua-resty-redis][]的基本使用方法([openresty/lua-resty-redis#README.md][README.md])。

安装 (Install)

    opm get anjia0532/lua-resty-redis-util

对比

截取官方部分代码,进行说明

        local redis = require "resty.redis"
        local red = redis:new()
    
        red:set_timeout(1000) -- 1 sec --设置超时时间
    
        local ok, err = red:connect("127.0.0.1", 6379) --设置redis的host和port
        if not ok then --判断生成连接是否失败
            ngx.say("failed to connect: ", err)
            return
        end
    
        ok, err = red:set("dog", "an animal") --插入键值(类似 mysql insert)
        if not ok then --判断操作是否成功
            ngx.say("failed to set dog: ", err)
            return
        end
    
        ngx.say("set result: ", ok) -- 页面输出结果
        -- put it into the connection pool of size 100,
        -- with 10 seconds max idle time
        local ok, err = red:set_keepalive(10000, 100) --将连接放入连接池,100个连接,最长10秒的闲置时间
        if not ok then --判断放池结果
            ngx.say("failed to set keepalive: ", err)
            return
        end
        -- 如果不放池,用完就关闭的话,用下面的写法
        -- or just close the connection right away:
        -- local ok, err = red:close()
        -- if not ok then
        --     ngx.say("failed to close: ", 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("failed to set dog:",err)
          return
        end
        -- 页面打印结果
        ngx.say("set result: ", ok) -- 页面输出结果

注意事项 (Note)

默认值 (Default Value)

    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 (1s)

  • keepalive: redis 连接池最大闲置时间,默认: 60000 (1m)

  • 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: receive: ", cjson.encode(res))
        end
    
        -- 再次获取
        res, err = func()
    
        -- 获取成功后,取消订阅 func(false)
        if res then
            ngx.say("2: receive: ", 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("failed to commit the pipelined requests: ", err)
            return
        else
            ngx.say("pipeline",cjson.encode(results))
        end
        -- output pipeline["OK","OK","Marry","Bob"]

script

参考 [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("failed to get the group info: ", err)
           return
        end
    
        ngx.say("script",res)

鸣谢 (Thanks)

本工具借鉴了 [lua-resty-redis/lib/resty/redis.lua][] 和 [Redis 接口的二次封装][linkRedis接口的二次封装] 的代码

反馈 (Feedback)

如果有问题,欢迎提 [issues][]

版权和许可

本模块采用 BSD 许可证。

版权所有 (C) 2017-,由 AnJia <[email protected]>。

保留所有权利。

在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用本软件,无论是否修改:

  • 源代码重新分发必须保留上述版权声明、此条件列表和以下免责声明。

  • 二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。

本软件由版权持有人和贡献者“按原样”提供,不提供任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保。在任何情况下,版权持有人或贡献者均不对因使用本软件而直接、间接、偶然、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润损失;或业务中断)负责,无论是在合同、严格责任或侵权(包括疏忽或其他)的任何理论下,即使已告知可能发生此类损害。

[openresty/lua-resty-redis]: https://github.com/openresty/lua-resty-redis [agentzh]: https://github.com/agentzh [README.md]: https://github.com/openresty/lua-resty-redis/blob/master/README.markdown [linkScript压缩复杂请求]: https://moonbingbing.gitbooks.io/openresty-best-practices/content/redis/script.html [openresty/lua-resty-redis#Synopsis]: https://github.com/openresty/lua-resty-redis/blob/master/README.markdown#synopsis [linkRedis接口的二次封装(发布订阅)]: https://moonbingbing.gitbooks.io/openresty-best-practices/content/redis/pub_sub_package.html [linkRedis接口的二次封装]: https://moonbingbing.gitbooks.io/openresty-best-practices/content/redis/out_package.html [lua-resty-redis/lib/resty/redis.lua]: https://github.com/openresty/lua-resty-redis/blob/master/lib/resty/redis.lua [issues]: https://github.com/anjia0532/lua-resty-redis-util/issues/new

作者

AnJia ([email protected])

许可证

2bsd

版本