基于lua-resty-redis的redis连接池 [轮]
@author karminski <[email protected]>
@version 161028:3
@link http://blog.eth6.org/src/wheel/redis_connection_pool_with_lua_nginx_module.html
这几天用oprensty写了一些东西, 在用lua-resty-redis连接redis的时候需要一个连接池, 原本想着这东西也没多难于是就手动撸了一个, 写完了接入到系统在测试的时候发现不妙了. 不但redis连接巨慢, 而且失败率也很高. RTFM之后终于写出了一个稳定版本.
模块分为这几个部分:
-- Pseudocode
<code #1>
redis_factory = function(redis_config)
h = redis_config
h.redis = lua-resty-redis
h.cosocket_pool = cosocket_pool config
h.commands = lua-resty-redis proxy commands name
h.connect = lua-resty-redis connect warp
h.spawn_client = function(): spawn redis-proxy-client -><code #2>
self = {}
self.pool = storage redis instance name
self.construct = function(): do your own construct
self.spawn = function(): call h.spawn_client() by name and storage spawned instance into ngx.ctx
self.destruct = function(): close and put into cosocket connection pool
end
<code #2>
spawn_client instance, aka redis-proxy-client = {
name = redis instance name
redis_instance = lua-resty-redis instance
connect = h.connect
connect_info = h.name
construct = function(): proxy lua-resty-redis all method into self
... (proxy function from lua-resty-redis)
}
原型部分:
h变量用来存储配置.
h.connect()函数封装了lua-resty-redis的连接方法.
h.spawn_client()方法用来生成包装lua-resty-redis的redis-proxy-client.
redis-proxy-client将lua-resty-redis内部的方法全部包装为自己内部的方法, 方法名称从h.commands指定.
redis-proxy-client中包含整个h变量的连接方法和连接参数, 该proxy构造过程将所有的proxy方法中均插入对lua-resty-redis产生的实例进行检测并重新连接的逻辑, 而且只在代理方法被调用时进行检测, 极大地缩短了redis实例初始化和使用之间的时间差, 同时又能克服与redis之间由于网络问题或设置问题导致的连接中断.
当redis_factory实例化后,返回的table包含以下几个方法:
self.construct()是预留的构造函数.
self.pool变量用来存储已经实例化的redis实例的名称.
redis-proxy-client.redis_instance, 真正的实例化的redis保存在redis-proxy-client.redis_instance,而redis-proxy-client则在redis_factory:spawn()过程中被保存在ngx.ctx中(必须将redis实例放置在ngx.ctx,否则会引起竞争导致命令请求失败).
self.destruct()用来销毁连接池中的所有redis实例, 其内部调用set_keepalive()后会立即将redis连接置为关闭状态. 并将redis连接放入ngx_lua cosocket连接池.
模块详细实现如下:
连接池代码:
--[[
redis_factory.lua
Redis factory method.
You can also find it at https://gist.github.com/karminski/33fa9149d2f95ff5d802
@version 151019:5
@author karminski
@license MIT
@changelogs
151019:5 CLEAN test code.