lua redis连接池

使用官方的redis库连接redis,https://github.com/openresty/lua-resty-redis

即使在 TCP 连接上启用了 keep-alive,再次调用 sock:connect() 也不会复用原先的连接。TCP Kepp-Alive 仅用于在连接空闲时发送探测包以确保连接的活跃状态,并不会影响到连接的创建和销毁。

但是在 lua 里面使用 ngx.socket.tcp 创建tcp连接时,设置了 Keep-Alive选项后,如果再次调用相同的 ngx.socket.tcp 对象的 connect 方法,会尝试复用原先的连接。因为在 openresty 中,ngx.socket.tcp 对象实际上是基于 nginx的内置连接池来管理连接的,当你使用 ngx.socket.tcp 创建连接时,实际上会从nginx的连接池中获取连接,如果连接池中已经存在可用的连接,会复用这些连接而不是创建新的连接。

因此在openresty 中,设置了 keep-alive 选项后,再次调用相同的 ngx.socket.tcp 对象的 connect 方法会尝试复用原先的连接,从而实现连接的复用。

测试步骤:

  1. 启动 openresty 容器

docker run -p 18001:18000 -v /luaobj:/alben -itd --name lua_test bitnami/openresty:1.21

  1. 编写lua脚本
    1. redis-utils.lua
local _M = {}
local redis = require("resty.redis")
local red_config = require('./redis-config')
local ip = red_config.redis['ip']
local port = red_config.redis['port']
local database = red_config.redis['database']
local auth = red_config.redis['auth']
local timeout = red_config.redis['timeout']
local max_idle_time = red_config.redis['max_idle_time']
local pool_size = red_config.redis['pool_size']
local unpack = unpack or table.unpack

function _M.exec(func)
  local red = redis:new()
  red:set_timeout(timeout)

  local ok, err = red:connect(ip, port)
  if not ok then
    ngx.say("redis","Cannot connect, host: " .. ip .. ", port: " .. port)
    ngx.log(ngx.ERR, "redis","Cannot connect, host: " .. ip .. ", port: " .. port)
    return nil, err
  end

  local count, err = red:get_reused_times()
  if 0 == count then
      ok, err = red:auth(auth)
      if not ok then
          ngx.say("failed to auth: ", err)
          ngx.log(ngx.ERR,"failed to auth: ", err)
          return
      end
  elseif err then
      ngx.say("failed to get reused times: ", err)
      ngx.log(ngx.ERR,"failed to get reused times: ", err)
      return
  end

  red:select(database)

  local res, err = func(red)
  if res then
      local ok, err1 = red:set_keepalive(max_idle_time, pool_size)
      if not ok then
        red:close()
      end
  end
  ngx.log(ngx.ERR,"redis resposne: ", res)
  return res, err
end


local res, err = _M.exec(
    function(red)
        return red:get("alben")
    end
)
ngx.say(res)

return _M
    1. redis-config.lua

local _M = { redis={ip="192.168.213.69",port="6379",database=1,timeout=100000,max_idle_time=60000,pool_size=5, auth=""} } return _M

  1. 修改openresty的nginx配置
    1. 在nginx.conf 里 http 下添加如下配置
lua_package_path "/alben/?.lua;;";
    1. 在 /opt/bitnami/openresty/nginx/conf 路径下新建目录 server_blocks,并在其中添加如下 配置 demo.conf
server {
    listen       18000;

    # 设置访问日志路径
    access_log      /alben/access.log;
    error_log       /alben/error.log;


    # 设置错误页面
    error_page  404              /404.html;
    location = /404.html {
        internal;
    }

    # 静态文件根目录
    location /redis {
        default_type 'text/plain';
        content_by_lua_file /alben/redis-utils.lua;
    }
}
  1. 测试在注释掉 redis-utils 里面 set_keepalive 和 不注释掉 set_keepalive 相关代码的情况下,对nginx的性能的影响,测试使用 apache 下 的ab测试工具:ab -n 10000 -c 10 http://127.0.0.1:18001/redis
    1. 不注释掉 set_keepalive:此时观察主机上和6379建立tcp连接的数量大约在50多(备注:设置的 pool_size 数目为5也可能会建立50多个连接)

    1. 注释掉 set_keepalive相关逻辑,openresty -s reload 重新加载配置,可以观察到测试结果如下,其中建立tcp连接的数量达到了6000多,且访问延时明显增大

参考文档:nginx中lua-redis使用_nginx lua redis-CSDN博客

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值