openresty开发系列26--openresty中使用redis模块
openresty开发系列26--openresty中使用redis模块
在一些高并发的场景中,我们常常会用到缓存技术,现在我们常用的分布式缓存redis是最知名的,
操作redis,我们需要引入redis模块 require "resty.redis";
我们现在做个可以操作redis进行赋值,读值的案例
一)连接redis服务器
---定义 redis关闭连接的方法
local function close_redis(red)
if not red then
return
end
local ok, err = red:close()
if not ok then
ngx.say("close redis error : ", err)
end
end
local redis = require "resty.redis" --引入redis模块
local red = redis:new() --创建一个对象,注意是用冒号调用的
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "10.11.0.215"
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then
ngx.say("connect to redis error : ", err)
return close_redis(red)
end
--调用API设置key
ok, err = red:set("msg", "hello world")
if not ok then
ngx.say("set msg error : ", err)
return close_redis(red)
end
--调用API获取key值
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
ngx.say("msg : ", resp)
close_redis(red)
请求结果 msg : hello world
--------------------------------
注意:得到的数据为空处理 ,redis返回的空 为null,所以不能用nil判断,而要用ngx.null判断
if resp == ngx.null then
resp = '' --比如默认值
end
--------------连接授权的redis-----------------
在redis.conf配置文件 配置认证密码
requirepass redis123
注意:windows 启动redis时,配置redis.windows.conf;并且不能直接 双击redis-server.exe,
如果双击启动,默认不会找此目录下的配置文件;需要指定配置文件
解决方案:
1)cmd窗口中 运行 redis-server.exe redis.windows.conf
2)新建一个bat批处理文件 文件内容 redis-server.exe redis.windows.conf
连接报错set msg error : NOAUTH Authentication required.因为认证出错
在red:connect成功后,调用red:auth认证密码
ok, err = red:auth("redis123")
if not ok then
ngx.say("failed to auth: ", err)
return close_redis(red)
end
二)redis连接池
redis的连接是tcp连接,建立TCP连接需要三次握手,而释放TCP连接需要四次握手,而这些往返时延仅需要一次,
以后应该复用TCP连接,此时就可以考虑使用连接池,即连接池可以复用连接。
我们需要把close_redis函数改造一下
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end
即设置空闲连接超时时间防止连接一直占用不释放;设置连接池大小来复用连接。
注意:
1、连接池是每Worker进程的,而不是每Server的;
2、当连接超过最大连接池大小时,会按照LRU算法回收空闲连接为新连接使用;
3、连接池中的空闲连接出现异常时会自动被移除;
4、连接池是通过ip和port标识的,即相同的ip和port会使用同一个连接池(即使是不同类型的客户端);
5、连接池第一次set_keepalive时连接池大小就确定下了,不会再变更;
注意:我们如何知道,redis连接对象是从连接池中获取的,还是新创建的连接呢??
使用 red:get_reused_times --->得到此连接被使用的次数
如果当前连接不是从内建连接池中获取的,该方法总是返回 0 ,也就是说,该连接还没有被使用过。
如果连接来自连接池,那么返回值永远都是非零。所以这个方法可以用来确认当前连接是否来自池子。
连接优化
采用连接池,连接带认证的redis
---定义 redis关闭连接的方法
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end
local redis = require "resty.redis" --引入redis模块
local red = redis:new() --创建一个对象,注意是用冒号调用的
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "10.11.0.215"
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then
ngx.say("connect to redis error : ", err)
return close_redis(red)
end
local count, err = red:get_reused_times()
if 0 == count then ----新建连接,需要认证密码
ok, err = red:auth("redis123")
if not ok then
ngx.say("failed to auth: ", err)
return
end
elseif err then ----从连接池中获取连接,无需再次认证密码
ngx.say("failed to get reused times: ", err)
return
end
--调用API设置key
ok, err = red:set("msg", "hello world333333333")
if not ok then
ngx.say("set msg error : ", err)
return close_redis(red)
end
--调用API获取key值
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
ngx.say("msg : ", resp)
close_redis(red)
=======================================
注意:连接池使用过程中,业务代码有select方法,会导致数据错乱
ok, err = red:select(1) --->选择db
if not ok then
ngx.say("failed to select db: ", err)
return
end
如:
A业务使用了db1,所以使用了 select(1);
B业务使用默认的db0,select(0)遗漏
但A,B业务共用了连接池,很有可能 B业务拿到的 A业务使用的连接,而此连接操作的数据库db1;
而B业务中代码没有指定select数据库,所以B业务操作数据到了db1中;导致数据错乱
转载于:https://www.cnblogs.com/reblue520/p/11434278.html
openresty开发系列26--openresty中使用redis模块相关推荐
- openresty开发系列36--openresty执行流程之6日志模块处理阶段
openresty开发系列36--openresty执行流程之6日志模块处理阶段 一)header_filter_by_lua 语法:header_filter_by_lua <lua-scri ...
- openresty开发系列27--openresty中封装redis操作
openresty开发系列27--openresty中封装redis操作 在关于web+lua+openresty开发中,项目中会大量操作redis, 重复创建连接-->数据操作-->关闭 ...
- openresty开发系列38--通过Lua+Redis 实现动态封禁IP
openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...
- openresty开发系列28--openresty中操作mysql
openresty开发系列28--openresty中操作mysql Mysql客户端 应用中最常使用的就是数据库了,尤其mysql数据库,那openresty lua如何操作mysql呢? ...
- openresty开发系列29--openresty中发起http请求
openresty开发系列29--openresty中发起http请求 有些场景是需要nginx在进行请求转发 用户浏览器请求url访问到nginx服务器,但此请求业务需要再次请求其他业务: 如用户请 ...
- openresty开发系列25--openresty中使用json模块
openresty开发系列25--openresty中使用json模块 web开发过程中,经常用的数据结构为json,openresty中封装了json模块,我们看如何使用 一)如何引入cjson模块 ...
- openresty开发系列24--openresty中lua的引入及使用
openresty开发系列24--openresty中lua的引入及使用 openresty 引入 lua 一)openresty中nginx引入lua方式 1)xxx_by_lua ---> ...
- openresty开发系列16--lua中的控制结构if-else/repeat/for/while
openresty开发系列16--lua中的控制结构if-else/repeat/for/while一)条件 - 控制结构 if-else if-else 是我们熟知的一种控制结构.Lua 跟其他语言 ...
- openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息
openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息 为了实现业务系统针对不同地区IP访问,展示包含不同地区信息的业务交互界面.很多情况下系统需要根据用户访问的IP信息 ...
最新文章
- Git 常用操作(3)- 本地分之显示、创建、切换、合并和删除操作
- group by总结(还有having)
- Docker报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
- 你要的Spring Boot多图片上传回显功能已经实现了,赶紧收藏吃灰~
- nginx反向代理和rewrite进行解决跨域问题、去掉url中的一部分字符串,通过nginx正则生成新的url...
- 第十三届“华中杯”大学生数学建模挑战赛题目 B 题 技术问答社区重复问题识别
- H3C 无线AP升级步骤
- 阿里云2011.9.17招聘会笔试题
- nand ubi - 5 kernel和ubi
- weka使用训练集分类测试集_科学网—使用独立测试集对分类模型进行评估 - 李向东的博文...
- constraintlayout_androidApi:ConstraintLayout
- div探索系列(二):让多个div显示在一行(浮动的div)
- 关于达梦监视器dmmonitor的一些知识
- 一周信创舆情观察(11.1~11.7)
- Windows安全加固
- python安装库之----有些库库真是小妖精
- java的public int_Java语言中“int”、“public”、“static int ”有什么区别?
- Qt通过ODBC连接虚谷数据库,并对数据库数据进行增删查改
- 图解通信原理与案例分析-30:6G-天地互联、陆海空一体、全空间覆盖的超宽带移动通信系统
- unittest安装教程_Unittest单元测试框架
热门文章
- 实例分析C语言中strlen和sizeof的区别
- Java-Web JSP指令、javabean和EL表达式
- 上海交大python答案_上海交通大学python期末考试样题加解析
- L2-004 这是二叉搜索树吗?-团体程序设计天梯赛GPLT
- 计算机机房门内开还是外开,卫生间的门是朝内开还是朝外开好?原来这样开,入住才方便!...
- 织梦的网站地图怎么做html,如何优化织梦dedecms默认网站地图sitemap.html??
- oracle数据连接java,java是与Oracle数据连接(jdbc)
- 阿里云 EventBridge 事件驱动架构实践
- Thoughtworks 正式成为阿里云云原生核心合作伙伴
- java 微信自定义菜单开发_微信公众号开发之设置自定义菜单实例代码【java版】...