openresty lua-resty-redis使用

        

            

                                          

lua-resty-redis 使用

           

redis:new():创建redis对象

语法格式:red, err = redis:new()

Creates a redis object. In case of failures, returns nil 
and a string describing the error
* 创建redis对象
* 如果创建失败,返回nil、错误信息error

               

connect:建立连接

# 语法格式
ok, err = red:connect(host, port, options_table?)
ok, err = red:connect("unix:/path/to/unix.sock", options_table?)

# optional_tables:可选参数
* ssl:boolean,是否使用ssl加密连接,默认false
* ssl_verify:是否验证ssl证书,默认false
* server_name: Specifies the server name for the new TLS extension 
                Server Name Indication (SNI) when connecting over SSL
* pool:连接池名称,如果不设置,默认为host:port、unix-socket-path
* pool_size:连接池大小,
             如果不设置,并且backlog也没有设置,连接池不会创建
             如果不设置,backlog设置了,连接池大小默认为:lua_socket_pool_size 
             连接池最多持有pool size个连接,但不会限制总连接,可通过设置backlog限制总连接
             超过pool size的连接会进入队列排队,如果队列满了,则报错
* backlog:超过连接池pool size的连接会进入队列排队,
           队列满了会报错:too many waiting connect operations

          

set_timeout:设置超时时间

语法格式:red:set_timeout(time)

Sets the timeout (in ms) protection for subsequent operations, 
including the connect method.
* 设置超时时间,单位毫秒

Since version v0.28 of this module, it is advised that set_timeouts 
be used in favor of this method
* 从0.28开始,推荐使用set_timeouts设置超时时间

            

set_timeouts:设置超时时间

语法格式:red:set_timeouts(connect_timeout, send_timeout, read_timeout)

Respectively sets the connect, send, and read timeout thresholds (in ms), 
for subsequent socket operations. Setting timeout thresholds with this 
method offers more granularity than set_timeout. As such, it is preferred 
to use set_timeouts over set_timeout.
* 单独设置连接、发送、读操作的超时时间,单位毫秒
* 推荐使用set_timeouts设置超时时间

              

set_keepalive:空闲连接存活时间

语法格式:ok, err = db:set_keepalive(max_idle_timeout, pool_size)
 
Puts the current Redis connection immediately into the 
ngx_lua cosocket connection pool.
* 将当前连接放到连接池
 
You can specify the max idle timeout (in ms) when the connection is 
in the pool and the maximal size of the pool every nginx worker process.
* 设置最大空闲时间、连接池大小(针对每个nginx worker)
 
In case of success, returns 1. In case of errors, returns nil with a string describing the error
* 设置成功,返回1
* 设置出错,返回nil,错误信息err

          

get_reused_times:连接重用次数,判断连接是否来自连接池

语法格式:times, err = db:get_reused_times()
 
This method returns the (successfully) reused times for the current connection. 
In case of error, it returns nil and a string describing the error.
* 获取当前连接的重复使用次数
* 如果出错,返回nil,错误信息err
 
If the current connection does not come from the built-in connection pool, then 
this method always returns 0, that is, the connection has never been reused (yet). 
If the connection comes from the connection pool, then the return value is always 
non-zero. So this method can also be used to determine if the current connection 
comes from the pool
* 如果当前连接不来自于连接池,返回0
* 如果当前连接来自连接池,返回一个非0值
* 这方法可用来判断当前连接是不是来自于连接池

                

close:关闭当前连接,一般是短连接,长连接使用连接池服用

语法格式:ok, err = db:close()
 
Closes the current mysql connection and returns the status.
* 关闭数据库连接,返回状态
 
In case of success, returns 1. In case of errors, returns 
nil with a string describing the error
* 关闭成功,返回1
* 关闭失败,返回nil、错误信息err

           

init_pipeline:流水线初始化

# 语法格式
red:init_pipeline()
red:init_pipeline(n)

Enable the redis pipelining mode. All subsequent calls to Redis command 
methods will automatically get cached and will send to the server in 
one run when the commit_pipeline method is called or get cancelled by 
calling the cancel_pipeline method.
* 开启流水线模式,所有的命令都会一次性的发送给redis服务器

This method always succeeds.
* 这方法总是会成功执行

If the redis object is already in the Redis pipelining mode, then 
calling this method will discard existing cached Redis queries.
* 如果已经开启了流水线模式,调用这个方法会丢弃查询缓存

The optional n argument specifies the (approximate) number of commands that 
are going to add to this pipeline, which can make things a little faster.
* n:表示最大可发送的命令

                  

commit_pipeline:提交流水线

语法格式:results, err = red:commit_pipeline()

Quits the pipelining mode by committing all the cached Redis queries 
to the remote server in a single run. All the replies for these queries 
will be collected automatically and are returned as if a big multi-bulk 
reply at the highest level.
* 提交流水线命令,随后返回命令结果

This method returns nil and a Lua string describing the error upon failures
* 如果执行失败,返回nil,错误信息error

           

cancal_pipeline:取消流水线

语法格式:red:cancel_pipeline()

Quits the pipelining mode by discarding all existing cached Redis 
commands since the last call to the init_pipeline method.
* 取消流水线,丢弃init_pipeline之后的所有的缓存命令

This method always succeeds.
* 该方法执行成功

If the redis object is not in the Redis pipelining mode, then 
this method is a no-op
* 如果redis不处于流水线模式,cancal_pipeline不执行任何操作

           

hmset:设置hash键值对

# 语法格式
res, err = red:hmset(myhash, field1, value1, field2, value2, ...)
res, err = red:hmset(myhash, { field1 = value1, field2 = value2, ... })

Special wrapper for the Redis "hmset" command.
When there are only three arguments (including the "red" object itself), 
then the last argument must be a Lua table holding all the field/value pairs
* 类似于hmset命令,设置hash结构键值对

           

array_to_hash:将数组转换为hash结构

语法格式:hash = red:array_to_hash(array)

Auxiliary function that converts an array-like Lua 
table into a hash-like table
* 将类数组的lua table结构转换为hash结构

             

read_reply:读取服务器的响应结果

语法格式:res, err = red:read_reply()

Reading a reply from the redis server. This method is mostly 
useful for the Redis Pub/Sub API
* 读取服务端的响应结果
* 该接口最常在发布订阅模式中使用


# 示例

    local cjson = require "cjson"
    local redis = require "resty.redis"

    local red = redis:new()
    local red2 = redis:new()

    red:set_timeouts(1000, 1000, 1000) -- 1 sec
    red2:set_timeouts(1000, 1000, 1000) -- 1 sec

    local ok, err = red:connect("127.0.0.1", 6379)
    if not ok then
        ngx.say("1: failed to connect: ", err)
        return
    end

    ok, err = red2:connect("127.0.0.1", 6379)
    if not ok then
        ngx.say("2: failed to connect: ", err)
        return
    end

    local res, err = red:subscribe("dog")
    if not res then
        ngx.say("1: failed to subscribe: ", err)
        return
    end

    ngx.say("1: subscribe: ", cjson.encode(res))

    res, err = red2:publish("dog", "Hello")
    if not res then
        ngx.say("2: failed to publish: ", err)
        return
    end

    ngx.say("2: publish: ", cjson.encode(res))

    res, err = red:read_reply()
    if not res then
        ngx.say("1: failed to read reply: ", err)
        return
    end

    ngx.say("1: receive: ", cjson.encode(res))

    red:close()
    red2:close()


# 操作结果
1: subscribe: ["subscribe","dog",1]
2: publish: 1
1: receive: ["message","dog","Hello"]

             

auth:权限认证

语法格式:res, err = red:auth(password)

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

    red:set_timeouts(1000, 1000, 1000) -- 1 sec

    local ok, err = red:connect("127.0.0.1", 6379)
    if not ok then
        ngx.say("failed to connect: ", err)
        return
    end

    local res, err = red:auth("foobared")
    if not res then
        ngx.say("failed to authenticate: ", err)
        return
    end

             

redis 事务

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

    red:set_timeouts(1000, 1000, 1000) -- 1 sec

    local ok, err = red:connect("127.0.0.1", 6379)
    if not ok then
        ngx.say("failed to connect: ", err)
        return
    end

    local ok, err = red:multi()     -- 开启事务命令
    if not ok then
        ngx.say("failed to run multi: ", err)
        return
    end
    ngx.say("multi ans: ", cjson.encode(ok))

    local ans, err = red:set("a", "abc")
    if not ans then
        ngx.say("failed to run sort: ", err)
        return
    end
    ngx.say("set ans: ", cjson.encode(ans))

    local ans, err = red:lpop("a")
    if not ans then
        ngx.say("failed to run sort: ", err)
        return
    end
    ngx.say("set ans: ", cjson.encode(ans))

    ans, err = red:exec()           -- 执行事务
    ngx.say("exec ans: ", cjson.encode(ans))

    red:close()

                

                      

                                          

使用示例

           

default.conf

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/local/openresty/nginx/html;
        index  index.html index.htm;
    }

    location /test {
        content_by_lua_block {
            local redis = require "resty.redis";
            local red = redis:new();

            red:set_timeouts(1000, 1000, 1000);

            local ok, err = red:connect("172.18.0.81", 6379);
            if not ok then
                ngx.say("failed to connect: ", err)
                return
            end

            ngx.say("red:set('1','gtlx')");
            local res, err = red:set('1','gtlx');
            if not res then
                ngx.say("failed to set: ", err)
                return
            end

            ngx.say("\nred:get('1')");
            res, err = red:get('1');
            if not res then
                ngx.say("failed to get: ", err)
                return
            end

            ngx.say("get读取结果 ==> ", res);

            ngx.say("\nred:mset('1','gtlx','2','hzw')");
            local res, err = red:mset('1','gtlx','2','hzw');
            if not res then
                ngx.say("failed to mset: ", err)
                return
            end
        
            ngx.say("\nred:mget('1','2')");
            res, err = red:mget('1','2');
            if not res then
                ngx.say("failed to mget: ", err)
                return
            end

            ngx.say("mget读取结果 == ", res);
        }
    }

    location /test2 {
        content_by_lua_block {
            local redis = require "resty.redis";
            local red = redis:new();

            red:set_timeouts(1000, 1000, 1000);

            local ok, err = red:connect("172.18.0.81", 6379);
            if not ok then
                ngx.say("failed to connect: ", err)
                return
            end

            ngx.say("redis 流水线操作");
            red:init_pipeline();
            red:set("3", "gtlx");
            red:set("4", "hzw");

            red:get("3");
            red:get("4");

            local results, err = red:commit_pipeline();
            if not results then
                ngx.say("流水线执行出错",err);
            end

            local cjson = require 'cjson';
            for key,value in pairs(results) do
                ngx.say(cjson.encode(value));
            end
        }
    }

    location /test3 {
        content_by_lua_block {
            local redis = require "resty.redis";
            local red = redis:new();

            red:set_timeouts(1000, 1000, 1000);

            local ok, err = red:connect("172.18.0.81", 6379);
            if not ok then
                ngx.say("failed to connect: ", err)
                return
            end

            ngx.say("redis 事务操作");
            local ok, err = red:multi();
            if not ok then
                ngx.say("事务开启失败: ", err)
                return
            end

            local cjson = require 'cjson';

            local res, err = red:set('1','gtlx');
            if not res then
                ngx.say("failed to set: ", err)
                return
            end
            ngx.say("set 操作 ==> ", cjson.encode(res));

            res, err = red:get('1');
            if not res then
                ngx.say("failed to get: ", err)
                return
            end
            ngx.say("get 操作 ==> ", cjson.encode(res));

            res, err = red:set('2','hzw');
            if not res then
                ngx.say("failed to set: ", err)
                return
            end
            ngx.say("set 操作2 ==> ", cjson.encode(res));

            res, err = red:exec();
            ngx.say("事务提交 ==> ", cjson.encode(res));
        }
    }

    location /test4 {
        content_by_lua_block {
            local cjson = require "cjson";
            local redis = require "resty.redis";
            local red = redis:new();
            local red2 = redis:new();

            red:set_timeouts(1000, 1000, 1000);

            local ok, err = red:connect("172.18.0.81", 6379);
            if not ok then
                ngx.say("red failed to connect: ", err)
                return
            end

            ok, err = red2:connect("172.18.0.81", 6379);
            if not ok then
                ngx.say("red2 failed to connect: ", err)
                return
            end

            ngx.say("redis 发布订阅操作");

            local res, err = red:subscribe("test");
            if not res then
                ngx.say("1 订阅失败 ==> ", err)
                return
            end

            ngx.say("1 订阅成功 ==> ", cjson.encode(res));

            res, err = red2:publish("test","gtlx");
            if not res then
                ngx.say("2 发布失败 ==> ", err)
                return
            end
            
            ngx.say("2 发布成功==> ", cjson.encode(res));

            res, err = red:read_reply()
            if not res then
                ngx.say("1 读取失败==> ", err)
                return
            end

            ngx.say("1 订阅成功 ==> ", cjson.encode(res));
        }
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/local/openresty/nginx/html;
    }

}

         

创建容器

docker run -it -d --net fixed --ip 172.18.0.82 -p 6001:80 \
-v /Users/huli/lua/openresty/redis/default.conf:/etc/nginx/conf.d/default.conf \
--name resty-redis lihu12344/openresty

        

使用测试

# set、get  mset、mget操作
huli@hudeMacBook-Pro redis % curl localhost:6001/test 
red:set('1','gtlx')

red:get('1')
get读取结果 ==> gtlx

red:mset('1','gtlx','2','hzw')

red:mget('1','2')
mget读取结果 == gtlxhzw


# 流水线操作
huli@hudeMacBook-Pro redis % curl localhost:6001/test2
redis 流水线操作
"OK"
"OK"
"gtlx"
"hzw"


# 事务操作
huli@hudeMacBook-Pro redis % curl localhost:6001/test3
redis 事务操作
set 操作 ==> "QUEUED"
get 操作 ==> "QUEUED"
set 操作2 ==> "QUEUED"
事务提交 ==> ["OK","gtlx","OK"]


# 发布订阅
huli@hudeMacBook-Pro redis % curl localhost:6001/test4
redis 发布订阅操作
1 订阅成功 ==> ["subscribe","test",1]
2 发布成功==> 1
1 订阅成功 ==> ["message","test","gtlx"]

          

                     

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐