openresty 学习笔记四:连接mysql和进行相关操作
openresty 学习笔记四:连接mysql和进行相关操作
毕竟redis是作为缓存,供程序的快速读写,虽然reidis也可以做持久化保存,但还是需要一个做数据存储的数据库。比如首次查询数据在redis查询不到则查询mysql,再将查询结果写过redis供下次查询。保存数据也可以先写入redis再通过队列使用另外的程序异步写入mysql。
后面会逐步把openresty写入rabbitmq和python通过订阅rabbitmq的队列将数据写入mysql得方法都整理一下。
先看看openresty如何对mysql进行连接和操作,并进行二次封装
mysql操作流程
通过resty.mysql库进行连接和操作
local mysql = require("resty.mysql")
local client, errmsg = mysql:new()
if not client then
return false, "mysql.socket_failed: " .. (errmsg or "nil")
end
client:set_timeout(10000)
local options = {
host = "127.0.0.1",
port = 3306,
user = "root",
password = "root",
database = "test"
}
local result, errmsg, errno, sqlstate = client:connect(options)
if not result then
return false, errmsg
end
local result, errmsg, errno, sqlstate = client:query(sql)
if not result then
errmsg = concat_db_errmsg("mysql.query_failed:", errno, errmsg, sqlstate)
end
self.close()
连接mysql的二次封装
这样做和连接redis一样,如果大量使用会需要不断重复代码和进行创建关闭与数据库的连接。所以这里也进行二次封装。
使用 set_keepalive(max_idle_timeout, pool_size) 替代 close() 将启用连接池特性。set_keepalive 的意思可以理解为,保持连接,并将连接归还到连接池内。这样在下次连接时,会首先会尝试从连接池获取连接,获取不成功才会创建新的连接。在高并发下,连接池能大大的减少连接 MySQL 和 Redis 的次数,明显的提升性能。
local mysql_c = require("resty.mysql")
local _M = {}
_M._VERSION = '0.01'
local mt = { __index = _M }
--[[ 先从连接池取连接,如果没有再建立连接.
返回:
false,出错信息.
true,数据库连接
--]]
function _M.get_connect(self)
if ngx.ctx[self] then
return true, ngx.ctx[self]
end
local client, errmsg = mysql_c:new()
if not client then
return false, "mysql.socket_failed: " .. (errmsg or "nil")
end
client:set_timeout(self.db_timeout)
local options = {
host = self.db_host,
port = self.db_port,
user = self.db_user,
password = self.db_password,
database = self.db_name
}
local result, errmsg, errno, sqlstate = client:connect(options)
if not result then
return false, errmsg
end
local query = "SET NAMES "..self.db_charset
local result, errmsg, errno, sqlstate = client:query(query)
if not result then
return false, errmsg
end
ngx.ctx[self] = client
return true, ngx.ctx[self]
end
--[[ 把连接返回到连接池
用set_keepalive代替close() 将开启连接池特性,可以为每个nginx工作进程,指定连接最大空闲时间,和连接池最大连接数
--]]
function _M.close(self)
if ngx.ctx[self] then
ngx.ctx[self]:set_keepalive(60000, 1000)
ngx.ctx[self] = nil
end
end
-- --[[ 查询有结果数据集时返回结果数据集
-- 无数据数据集时返回查询影响返回:
-- false,出错信息,sqlstate结构.
-- true,结果集,sqlstate结构.
-- --]]
function _M.mysql_query(self ,sql)
local ret, client = self:get_connect()
if not ret then
return false, client, nil
end
local result, errmsg, errno, sqlstate = client:query(sql)
if not result then
errmsg = concat_db_errmsg("mysql.query_failed:", errno, errmsg, sqlstate)
return false, errmsg, sqlstate
end
self.close()
return true, result, sqlstate
end
function _M.query(self ,sql)
local ret, res, _ = self:mysql_query(sql)
if not ret then
ngx.log(ngx.ERR, "query db error. res: " .. (res or "nil"))
return nil
end
return res[1]
end
function _M.execute(sql)
local ret, res, sqlstate = self:mysql_query(sql)
if not ret then
ngx.log(ngx.ERR, "mysql.execute_failed. res: " .. (res or 'nil') .. ",sql_state: " .. (sqlstate or 'nil'))
return -1
end
return res.affected_rows
end
function _M.new(self, opts)
opts = opts or {}
local db_host = opts.host or '127.0.0.1'
local db_port = opts.port or 3306
local db_user = opts.user or 'root'
local db_password = opts.password or ' '
local db_name = opts.db_name or 'test'
local db_timeout = opts.db_timeout or 10000
local db_charset = opts.charset or 'utf8'
return setmetatable({
db_host = db_host,
db_port = db_port,
db_user = db_user,
db_password = db_password,
db_name = db_name,
db_timeout = db_timeout,
db_charset = db_charset }, mt)
end
return _M
使用示例
local mysqlPool = require ("mysqlPool")
local mysql = mysqlPool:new()
local mysqlCodeRes = mysql:query('SELECT type,enable_flag,count FROM access_code where code = 123')
小tips
如果数据库地址是用使用域名,需要设置nginx的域名解析服务器。在nginx.conf配置,实际情况根据所在网络的DNS进行填写
resolver 10.138.224.65;
resolver_timeout 30s;
openresty 学习笔记四:连接mysql和进行相关操作的更多相关文章
- openresty 学习笔记三:连接redis和进行相关操作
openresty 学习笔记三:连接redis和进行相关操作 openresty 因其非阻塞的调用,令服务器拥有高性能高并发,当涉及到数据库操作时,更应该选择有高速读写速度的redis进行数据处理.避 ...
- SQL学习笔记四之MySQL数据操作
阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: DML =========== ...
- robot framework学习笔记之七—连接mysql数据库
1.安装Database-Library 输入命令:pip install robotframework_databaselibrary 2.添加Database的Library 3.实例 * ...
- MYSQL进阶学习笔记四:MySQL存储过程之定义条件,处理过程及存储过程的管理!(视频序号:进阶_11,12)
知识点五:MySQL存储过程之定义条件和处理过程及存储过程的管理(11,12) 定义条件和处理: 条件的定义和处理可以用来定义在处理过程中遇到的问题时相应的处理步骤. DECLARE CONTINUE ...
- C# LINQ学习笔记四:LINQ to OBJECT之操作文件目录
本笔记摘抄自:https://www.cnblogs.com/liqingwen/p/5816051.html,记录一下学习过程以备后续查用. 许多文件系统操作实质上是查询,因此非常适合使用LINQ方 ...
- MySql学习笔记四
MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...
- openresty 学习笔记一:环境安装
openresty 学习笔记一:环境安装 openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭 ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
随机推荐
- NoSQL & Redis 介绍、缓存穿透 & 击穿 & 雪崩
1. NoSql 简介 2. Redis 简介 2.1 Redis 的起源 2.2 缓存过期 & 缓存淘汰 3. 缓存异常 1)缓存穿透 2)缓存击穿 3)缓存雪崩 4)总结 1. NoSQL ...
- 一次错误使用 go-cache 导致出现的线上问题
话说一个美滋滋的上午, 突然就出现大量报警, 接口大量请求都响应超时了. 排查过程 查看服务器的监控系统, CPU, 内存, 负载等指标正常 排查日志, 日志能够响应的结果也正常. request.l ...
- mysql索引性能验证,高性能的索引策略
索引性能验证 1.无索引列的查询 在where条件中查询没有添加索引的列,性能会比较差.我们可以先在sqlyog中打开表t_user的数据,然后复制一个名字出来进行查询. /*无索引列的查询,索引不会 ...
- 根据数据源自定义字段实现动态导出Excel
前言 最近遇到了一个需求,需要导出各种订单数据,可能是因为懒吧,不想重新写查询然后导出数据:就有了下边的这些操作了. 具体实现方式 1),定义一个泛型类来接收我们要导出的数据源,(需要EPPlus包) ...
- Python语言程序设计(笔记)
1.平方根的格式化 知识点:平方根计算 pow(a,0.5)[可以计算负数,结果为复数] a**b 例题: 获得用户输入的一个整数a,计算a的平方根,保留小数点后3位,并打印输出. ...
- 数据链路层协议(Ethernet、IEEE802.3、PPP、HDLC)
目录 数据链路层协议 Ethernet以太网协议 以太网数据帧的封装 IEEE802.3协议 PPP协议 HDLC协议 数据链路层协议 首先Ethernet.IEEE802.3.PPP和HDLC都是数 ...
- 学习Canvas绘图与动画基础 绘制直线(二)
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="U ...
- SSM中事务的配置模板
Spring-tx.xml 配置思路: 1. 声明事务管理器DataSourceTransactionManager,并注入数据源dataSource属性 2.配置事务增强<tx:advice& ...
- spring boot的ComponentScan和ServletComponentScan注解
ComponentScan 这个注解可以扫描带@Component的类.众所皆知,@RestController和@Configuration和@Service和@Configuration等都有带C ...
- 浅析DDD——领域驱动设计的理解
浅析DDD--领域驱动设计的理解 我觉得领域驱动设计概念的提出,是为了更清晰的区分边界.这里的边界包括业务边界和功能的边界,每个边界都包含具体的领域对象,当业务和功能的领域对象一一对应上之后,业务的变 ...