基于lua-resty-redis的redis连接池-程序员宅基地

技术标签: 运维  lua  数据库  

基于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.
               
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34281537/article/details/89427893

智能推荐

认识 Iconfont 以及什么是 .eot、.woff、.ttf、.svg-程序员宅基地

2019独角兽企业重金招聘Python工程师标准>>> ...

中国大学MOOC(C语言程序设计精髓)作业-程序员宅基地

第六周 练兵区编程题1、绘制金字塔(4分)题目内容:要求用户从键盘输入一个大写字母,使用嵌套循环产生像下面这样的金字塔图案:AABAABCBAABCDCBA程序运行结果示例1:Please input a capital:D____A___ABA__ABCBA_ABCDCBA程序运行结果示例2:Please input a capital:F______A...

微信公众账号调取用户昵称和用户头像_公众号获取头像昵称-程序员宅基地

微信服务号获取用户信息最近在做一个活动页面,要求获取用户的昵称和头像,于是研究了一下,直接上步骤(注意只有服务号可以获取)参考文档网页授权获取用户基本信息参考文档首先设置公众号的授权回调域名先进入公众号,点击开发者中心然后在授权接口权限表中找到如图所示的项目并且点击修改最后配置你的回调域名,注意要用外网地址然后上代码//这个设置你的授权回调地址$base = '';//这个设置你的appid$a_公众号获取头像昵称

Python3基础:04_字符串、列表、元组、字典和集合-程序员宅基地

这篇文章将对字符串、列表、元组、字典和集合的知识点以及它们之间的异同作出总结。

欢迎使用CSDN-markdown编辑器-程序员宅基地

本文转载,原文地址:http://blog.csdn.net/fulinus/article/details/9669177#comments1、文件描述符在内核中数据结构  在具体说dup/dup2之前,我认为有必要先了解一下文件描述符在内核中的形态。一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2),0与进程的

了解一些关于单片机的常识_如何理解单片机电平_雷丶Ray的博客-程序员宅基地

一、电平特性:TTL电平:>2.4V为高电平,<0.4V为低电平。计算机串口使用的是RS232电平。将RS232电平转换为TTL电平单片机才能识别。(用电平转换芯片)二、IO口:单片机对外围设备的控制都是通过IO口来进行的(输出高低电平);接受外部控制也是通过IO口来读取外部电压信号。P开头的为IO口。三、单片机的基本时序:1、振荡周期:也称时钟周期,是指为单片机提供数时钟脉冲信号的振荡源的周期。2、机器周期:一个机器周期包含12个时钟周期。在一个机器周期内,CPU可以完成一个独_如何理解单片机电平

随便推点

插入排序:直接插入、折半插入排序源码及时间复杂度_折半插入最好时间-程序员宅基地

插入排序的方法: 不断将无序队列的元素加入到有序队列中。直接插入排序源码template //insert_sortint sort(T *t, int n){ int compare_times = 0; for(int i=1; i

UG12.0实战模具编程 拆电极 模芯钢料编程视频教程-程序员宅基地

UG12.0实战模具编程 拆电极 模芯钢料编程视频教程链接:https://pan.baidu.com/s/1ZFrMnE5xySR26L1IzzjCqw提取码:6due

QT通过ODBC来连接sqlsever 2008数据库-程序员宅基地

文件头添加#include&lt;QtSql/QtSql&gt;工程文件pro中添加QT += sql//连接数据库函数如下: QSqlDatabase db=QSqlDatabase::addDatabase("QODBC");//利用odbc连接sqlsever db.setDatabaseName(QString("DRIVER={SQL SERVER};" ...

浩易南:年赚10万怎么玩-程序员宅基地

我08年就轻轻松松做到了年赚10万,确切地说是做到了年赚30万,而且还在08年买了房。我也知道,我赚多少钱,并没人在意。大家最在意的是:我是怎么做到的。今天就简单给大家聊一聊(擦边的就不聊了,只适合地面小范围讲)。我年赚10万,是卖手机靓号赚的,而且是一年只出了十几单。我到底是怎么操作的?1:建立手机靓号数据库。淘宝上所有卖手机靓号的人,我都加了他们的旺旺,大概加了3000多人。确切地

python爬虫通过图片原始url请求图片然后上传到oss中并返回图片新的url-程序员宅基地

简单上传提供上传字符串、上传Bytes、上传Unicode、上传网络流以及上传本地文件五种形式。通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型:类型上传方式字符串直接上传Bytes直接上传Unicode自动转换为UTF-8编码的Bytes进行上传本地文件文件对象(File Object),必须以...

ThinkPHP中的exp查询_thinkphp5.1 whereexp-程序员宅基地

select * from vendor where vendor_id = vendor_f_id在thinkphp中为了代码的简洁以及通用性,不考虑使用原生的方式进行sql的查询,而是采用查询map的方式进行查询$condition[ 'vendor_f_id' ] = 'vendor_id';但是,thinkphp在处理上述条件的时候,将其转化为了以下代码:select * f..._thinkphp5.1 whereexp

推荐文章

热门文章

相关标签