最近剛剛接手同事的OpenResty的項目,發現對mysql,redis的操作沒有用連接池,故對此進行了改造。
MYSQL
主要是通過mysql_pool.lua 和 dbutil.lua 來封裝對數據庫的操作
mysql_pool.lua:
1 module("mysql_pool", package.seeall) 2 3 local dbConfig = require"config" 4 local mysql = require("resty.mysql") 5 6 local mysql_pool = {} 7 8 --[[ 9 先從連接池取連接,如果沒有再建立連接. 10 返回: 11 false,出錯信息. 12 true,數據庫連接 13 --]] 14 function mysql_pool:get_connect() 15 if ngx.ctx[mysql_pool] then 16 return true, ngx.ctx[mysql_pool] 17 end 18 19 local client, errmsg = mysql:new() 20 if not client then 21 return false, "mysql.socket_failed: " .. (errmsg or "nil") 22 end 23 24 client:set_timeout(10000) --10秒 25 26 local options = { 27 host = dbConfig.DBHOST, 28 port = dbConfig.DBPORT, 29 user = dbConfig.DBUSER, 30 password = dbConfig.DBPASSWORD, 31 database = dbConfig.DBNAME 32 } 33 34 local result, errmsg, errno, sqlstate = client:connect(options) 35 if not result then 36 return false, "mysql.cant_connect: " .. (errmsg or "nil") .. ", errno:" .. (errno or "nil") .. 37 ", sql_state:" .. (sqlstate or "nil") 38 end 39 40 local query = "SET NAMES " .. dbConfig.DEFAULT_CHARSET 41 local result, errmsg, errno, sqlstate = client:query(query) 42 if not result then 43 return false, "mysql.query_failed: " .. (errmsg or "nil") .. ", errno:" .. (errno or "nil") .. 44 ", sql_state:" .. (sqlstate or "nil") 45 end 46 47 ngx.ctx[mysql_pool] = client 48 return true, ngx.ctx[mysql_pool] 49 end 50 51 --[[ 52 把連接返回到連接池 53 用set_keepalive代替close() 將開啟連接池特性,可以為每個nginx工作進程,指定連接最大空閑時間,和連接池最大連接數 54 --]] 55 function mysql_pool:close() 56 if ngx.ctx[mysql_pool] then 57 ngx.ctx[mysql_pool]:set_keepalive(60000, 1000) 58 ngx.ctx[mysql_pool] = nil 59 end 60 end 61 62 --[[ 63 查詢 64 有結果數據集時返回結果數據集 65 無數據數據集時返回查詢影響 66 返回: 67 false,出錯信息,sqlstate結構. 68 true,結果集,sqlstate結構. 69 --]] 70 function mysql_pool:query(sql, flag) 71 local ret, client = self:get_connect(flag) 72 if not ret then 73 return false, client, nil 74 end 75 76 local result, errmsg, errno, sqlstate = client:query(sql) 77 self:close() 78 79 if not result then 80 errmsg = concat_db_errmsg("mysql.query_failed:", errno, errmsg, sqlstate) 81 return false, errmsg, sqlstate 82 end 83 84 return true, result, sqlstate 85 end 86 87 return mysql_pool
dbutil.lua

1 module("dbutil", package.seeall) 2 local mysql_pool = require("mysql_pool") 3 4 function query(sql) 5 6 local ret, res, _ = mysql_pool:query(sql) 7 if not ret then 8 ngx.log(ngx.ERR, "query db error. res: " .. (res or "nil")) 9 return nil 10 end 11 12 return res 13 end 14 15 function execute(sql) 16 17 local ret, res, sqlstate = mysql_pool:query(sql) 18 if not ret then 19 ngx.log(ngx.ERR, "mysql.execute_failed. res: " .. (res or 'nil') .. ",sql_state: " .. (sqlstate or 'nil')) 20 return -1 21 end 22 23 return res.affected_rows 24 end
REDIS
redis_pool.lua:
1 module("redis_pool", package.seeall) 2 3 local redisConfig = require"config" 4 local redis = require("resty.redis") 5 6 local redis_pool = {} 7 8 --[[ 9 先從連接池取連接,如果沒有再建立連接. 10 返回: 11 false,出錯信息. 12 true,redis連接 13 --]] 14 function redis_pool:get_connect() 15 if ngx.ctx[redis_pool] then 16 return true, ngx.ctx[redis_pool] 17 end 18 19 local client, errmsg = redis:new() 20 if not client then 21 return false, "redis.socket_failed: " .. (errmsg or "nil") 22 end 23 24 client:set_timeout(10000) --10秒 25 26 local result, errmsg = client:connect(redisConfig.REDIS_HOST, redisConfig.REDIS_PORT) 27 if not result then 28 return false, errmsg 29 end 30 31 ngx.ctx[redis_pool] = client 32 return true, ngx.ctx[redis_pool] 33 end 34 35 function redis_pool:close() 36 if ngx.ctx[redis_pool] then 37 ngx.ctx[redis_pool]:set_keepalive(60000, 300) 38 ngx.ctx[redis_pool] = nil 39 end 40 end 41 42 return redis_pool