OpenResty高并发最佳实践--Redis操作_一行Java的博客-CSDN博客_resty.redis


本站和网页 https://blog.csdn.net/lupengfei1009/article/details/86160652 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

OpenResty高并发最佳实践--Redis操作_一行Java的博客-CSDN博客_resty.redis
OpenResty高并发最佳实践--Redis操作
一行Java
于 2019-01-09 17:24:30 发布
7369
收藏
分类专栏:
OpenResty
文章标签:
OpenResty
redis连接池
Lua操作redis
OpenResty操作redis
Lua redis连接池
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lupengfei1009/article/details/86160652
版权
OpenResty
专栏收录该内容
5 篇文章
5 订阅
订阅专栏
文章目录
前言准备代码走起测试
前言
使用到了OpenResty,很核心的目的是为了解决高并发的问题,为了不让数据库成为高并发的瓶颈,那么操作redis就变的不可避免了,下面介绍OpenResty操作redis的过程
准备
不了解OpenResty的可以参考以下文章 OpenResty(Nginx+Lua)高并发最佳实践 Window下基于ZeroBrane Studio开发调试OpenResty
代码走起
redis连接池(工具类) 在OpenResty的lualib目录下创建testcode文件夹,用于放置我们的测试lua脚本,并在文件夹下创建redis_factory.lua,如下图: 将以下代码拷贝至该文件(不需要做任何修改): local redis_factory = function(h)
local h = h
h.redis = require('resty.redis')
h.cosocket_pool = {max_idel = 10000, size = 10000}
h.commands = {
"append", "auth", "bgrewriteaof",
"bgsave", "bitcount", "bitop",
"blpop", "brpop",
"brpoplpush", "client", "config",
"dbsize",
"debug", "decr", "decrby",
"del", "discard", "dump",
"echo",
"eval", "exec", "exists",
"expire", "expireat", "flushall",
"flushdb", "get", "getbit",
"getrange", "getset", "hdel",
"hexists", "hget", "hgetall",
"hincrby", "hincrbyfloat", "hkeys",
"hlen",
"hmget", "hmset", "hscan",
"hset",
"hsetnx", "hvals", "incr",
"incrby", "incrbyfloat", "info",
"keys",
"lastsave", "lindex", "linsert",
"llen", "lpop", "lpush",
"lpushx", "lrange", "lrem",
"lset", "ltrim", "mget",
"migrate",
"monitor", "move", "mset",
"msetnx", "multi", "object",
"persist", "pexpire", "pexpireat",
"ping", "psetex", "psubscribe",
"pttl",
"publish", "punsubscribe", "pubsub",
"quit",
"randomkey", "rename", "renamenx",
"restore",
"rpop", "rpoplpush", "rpush",
"rpushx", "sadd", "save",
"scan", "scard", "script",
"sdiff", "sdiffstore",
"select", "set", "setbit",
"setex", "setnx", "setrange",
"shutdown", "sinter", "sinterstore",
"sismember", "slaveof", "slowlog",
"smembers", "smove", "sort",
"spop", "srandmember", "srem",
"sscan",
"strlen", "subscribe", "sunion",
"sunionstore", "sync", "time",
"ttl",
"type", "unsubscribe", "unwatch",
"watch", "zadd", "zcard",
"zcount", "zincrby", "zinterstore",
"zrange", "zrangebyscore", "zrank",
"zrem", "zremrangebyrank", "zremrangebyscore",
"zrevrange", "zrevrangebyscore", "zrevrank",
"zscan",
"zscore", "zunionstore", "evalsha",
-- resty redis private command
"set_keepalive", "init_pipeline", "commit_pipeline",
"array_to_hash", "add_commands", "get_reused_times",
-- connect
-- @param table connect_info, e.g { host="127.0.0.1", port=6379, pass="", timeout=1000, database=0}
-- @return boolean result
-- @return userdata redis_instance
h.connect = function(connect_info)
local redis_instance = h.redis:new()
redis_instance:set_timeout(connect_info.timeout)
if not redis_instance:connect(connect_info.host, connect_info.port) then
return false, nil
end
if connect_info.pass ~= '' then
redis_instance:auth(connect_info.pass)
end
redis_instance:select(connect_info.database)
return true, redis_instance
end
-- spawn_client
-- @param table h, include config info
-- @param string name, redis config name
-- @return table redis_client
h.spawn_client = function(h, name)
local self = {}
self.name = ""
self.redis_instance = nil
self.connect = nil
self.connect_info = {
host = "", port = 0, pass = "",
timeout = 0, database = 0
-- construct
self.construct = function(_, h, name)
-- set info
self.name = name
self.connect = h.connect
self.connect_info = h[name]
-- gen redis proxy client
for _, v in pairs(h.commands) do
self[v] = function(self, ...)
-- instance test and reconnect
if (type(self.redis_instance) == 'userdata: NULL' or type(self.redis_instance) == 'nil') then
local ok
ok, self.redis_instance = self.connect(self.connect_info)
if not ok then return false end
end
-- get data
local vas = { ... }
return self.redis_instance[v](self.redis_instance, ...)
end
end
return true
end
-- do construct
self:construct(h, name)
return self
end
local self = {}
self.pool = {} -- redis client name pool
-- construct
-- you can put your own construct code here.
self.construct = function()
return
end
-- spawn
-- @param string name, redis database serial name
-- @return boolean result
-- @return userdata redis
self.spawn = function(_, name)
if self.pool[name] == nil then
ngx.ctx[name] = h.spawn_client(h, name)
self.pool[name] = true
return true, ngx.ctx[name]
else
return true, ngx.ctx[name]
end
end
-- destruct
-- @return boolean allok, set_keepalive result
self.destruct = function()
local allok = true
for name, _ in pairs(self.pool) do
local ok, msg = ngx.ctx[name].redis_instance:set_keepalive(
h.cosocket_pool.max_idel, h.cosocket_pool.size
if not ok then allok = false end
end
return allok
end
-- do construct
self.construct()
return self
end
return redis_factory
配置文件 同级目录下创建config_constant.lua,用于防止redis或者其他的公共配置文件 将以下代码拷贝至该文件,具体配置数据请根据自己的redis数据库的情况修改 config = {}
config.redisConfig = {
redis_a = { -- your connection name
--ip
host = '127.0.0.1',
--端口
port = 6379,
--密码
pass = '123456789',
--超时时间,如果是测试环境debug的话,这个值可以给长一点;如果是正式环境,可以设置为200
timeout = 120000,
--redis的库
database = 0,
},
-- redis_b = {
-- -- host = '127.0.0.1',
-- -- port = 6379,
-- -- pass = '',
-- -- timeout = 200,
-- -- database = 0,
-- -- },
return config
测试
编写测试脚本 前端传递需要查询的key,将key的值取出来并返回给前端 在testcode文件下创建redistest.lua并拷贝一下至该文件 --平台公共的配置文件常量
local config = require "testcode.config_constant"
--redis连接池工厂
local redis_factory = require('testcode.redis_factory')(config.redisConfig) -- import config when construct
--获取redis的连接实例
local ok, redis_a = redis_factory:spawn('redis_a')
--用于接收前端数据的对象
local args=nil
--获取前端的请求方式 并获取传递的参数
local request_method = ngx.var.request_method
--判断是get请求还是post请求并分别拿出相应的数据
if"GET" == request_method then
args = ngx.req.get_uri_args()
elseif "POST" == request_method then
ngx.req.read_body()
args = ngx.req.get_post_args()
--兼容请求使用post请求,但是传参以get方式传造成的无法获取到数据的bug
if (args == nil or args.data == null) then
args = ngx.req.get_uri_args()
end
end
--获取前端传递的key
local key = args.key
--在redis中获取key对应的值
local va = redis_a:get(key)
--响应前端
ngx.say('{"key":"'..key..'","va":"'..va..'"}')
配置OpenResty下Nginx的Lua文件关联 在nginx.con中的80配置下添加如下配置 location /redis
default_type text/html;
#这里的lua文件的路径为绝对路径,请根据自己安装的实际路径填写
#记得斜杠是/这个,从window中拷贝出来的是\这样,这样是有问题的,务必注意
content_by_lua_file F:/DATA/software/other/openresty-1.13.6.2-win32/lualib/testcode/redistest.lua;
重启OpenResty的Nginx nginx -s reload 准备redis的测试数据 测试 浏览器请求:http://127.0.0.1/redis?key=a 出现以下结果,则正常测试成功
到此,Lua操作redis完成!!!
一行Java
关注
关注
点赞
收藏
打赏
评论
OpenResty高并发最佳实践--Redis操作
文章目录前言准备代码走起测试前言使用到了OpenResty,很核心的目的是为了解决高并发的问题,为了不让数据库成为高并发的瓶颈,那么操作redis就变的不可避免了,下面介绍OpenResty操作redis的过程准备不了解OpenResty的可以参考以下文章OpenResty(Nginx+Lua)高并发最佳实践Window下基于ZeroBrane Studio开发调试OpenResty...
复制链接
扫一扫
专栏目录
lua-resty-redis-connector:lua-resty-redis的连接实用程序
02-03
lua-resty-redis-connector:lua-resty-redis的连接实用程序
OpenResty第六篇: OpenResty连接Redis 以及模块开发
yangsen159的博客
07-24
1283
Lua模块开发
在实际的开发过程中,不可能把所有的lua代码写在一个lua文件中,通常的做法将特定功能的放在一个lua文件中,即用lua模块开发。在lualib目录下,默认有以下的lua模块。
lualib/
├── cjson.so
├── ngx
│ ├── balancer.lua
│ ├── ocsp.lua
│ ├── re.lua
│ ├── semaphore.lua...
评论 2
您还未登录,请先
登录
后发表或查看评论
OpenResty 对接Redis,并读写数据
03-01
556
使用场景,静态资源写入的redis中,以及数据读取
openresty-redis操作
u013008898的博客
03-22
835
我们这里将配置文件写在一个文件夹下
redis_factory.lua:
local redis_factory = function(h)
local h = h
h.redis = require('resty.redis')
h.cosocket_pool = {max_idel = 10000, size = 10000}
h.commands = {
"append".
Openresty+Redis自动封禁访问频率过高IP
weixin_43268590的博客
03-27
2576
Openresty+Redis安装在公网IP为x.x.x.x的服务器上下载安装的软件版本:openresty-1.19.3.2+redis-4.0.10实现思路:通过在Nginx上进行访问限制,通过Lua来灵活实现业务需求,而Redis用于存储黑名单列表。研究目标:nginx中使用lua脚本及nginx直接访问redis。需要下载安装的内容:openresty和redis命令:yum install -y gcc gcc-c++ readline-devel pcre-devel openssl-devel
openresty lua-resty-redis使用
最新发布
weixin_43931625的博客
07-13
718
openresty lua-resty-redis使用
基于lua-resty-redis的redis连接池
weixin_34281537的博客
01-18
3912
基于lua-resty-redis的redis连接池 [轮]
@author karminski <code.karminski@outlook.com>
@version 161028:3
@link http://blog.eth6.org/src/wheel/redis_connection_p...
OpenResty连接Redis
Fouy_风度玉门。
08-05
2679
通常来说,对于OpenResty的应用多数都会用到Redis,用以减少回源次数,从而加速网站。话不多说,先上一个demo
redis_iresty.lua
-- file name: resty/redis_iresty.lua
local redis_c = require "resty.redis"
local ok, new_tab = pcall(require,
其实你可以不必Redis exists
|] 大世界,小人物
08-17
1万+
今天,不小心看到一段代码,因之前优化过类似的问题。但是这种问题一而再再而三出现,真心觉得码农,也不是谁都能当好的。细节决定成败,做事情的风格,真真的会阻碍一个人的发展。
废话不多说,直接上代码:
//不友好使用方式
if(jedis.exists(key)){
String value = jedis.get(key);
do("目标代码1");
//……
}else{
do(...
利用 Lua 的函数式编程简化 lua-resty-redis 的使用
weixin_34209406的博客
10-18
381
在利用 OpenResty 编写高性能服务的时候,很有可能会使用到 Redis。在 OpenResty 中,我们通常使用 lua-resty-redis 这个模块操作 Redis。
在 lua-resty-redis 的示例中,我们可以总结出以下几个步骤:
导入 resty.redis 模块
实例化 redis 对象:
local r...
10.高并发Lua、OpenResty、redis
小白的博客
03-12
4034
变更频率低的数据,查询频率高得数据,如何提升访问速度?
数据做成静态页[商品详情页]
做缓存[Redis]
Lua入门
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用
程序中,从而为应用程序提供灵活的扩展和定制功能
特性
支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
语言内置模式匹
openresty开发系列26--openresty中使用redis模块
reblue520的专栏
08-30
509
openresty开发系列26--openresty中使用redis模块在一些高并发的场景中,我们常常会用到缓存技术,现在我们常用的分布式缓存redis是最知名的,操作redis,我们需要引入redis模块 require "resty.redis";我们现在做个可以操作redis进行赋值,读值的案例一)连接redis服务器---定义 redis关闭连接的方法local function...
[记录点滴] OpenResty中Redis操作总结
罗西的思考
06-20
440
本文总结了在OpenResty中的操作,与大家分享,涉及知识点为Openresty, Lua, Redis。
openresty开发系列27--openresty中封装redis操作
reblue520的专栏
08-30
787
openresty开发系列27--openresty中封装redis操作在关于web+lua+openresty开发中,项目中会大量操作redis,重复创建连接-->数据操作-->关闭连接(或放到连接池)这个完整的链路调用完毕,甚至还要考虑不同的 return 情况做不同处理,就很快发现代码中有大量的重复推荐一个二次封装的类库-------------------------...
OpenResty+Keepalived组建高可用集群+双主模式
weixin_34238633的博客
07-24
657
* 环境:
system version:CentOS Linux release 7.5.1804 (Core) 3.10.0-862.9.1.el7.x86_64nginx version:openresty/1.13.6.1keepalive version:keepalived-2.0.6
OpenResty安装
[root@localhost soft]# yum install y...
Openresty(十四)openresty通过lua操作redis
wzj_110的博客
09-12
802
一 openresty官方自带的redis模块
openresty自带lua module的设计思路
(1)支持的redis命令
其它方面提供的
(2)连接相关的
① new
② set_timeout
③ connect
④ auth
nginx+lua+redis实现token验证
项目地址
⑤ 使用common_cmds中提供的redis指令
local redis = require "re...
openresty 网关rsa+aes+redis鉴权解密
胡汉三
07-11
635
之前使用了openresty进行了rsa跟aes的加解密测试。现在我们整合一下、使用openresty连接redis做鉴权、解密。之前提到过,我们不使用cookie而是使用token来认证用户信息。而且token是我们自己加密的、加密的规则就是使用aes进行加密。我们再来缕一缕整个流程。客户端(浏览器)流程: 第一步:先获取token(临时token),返回的token是aes加密的,这里的密钥我们就使用固定的aes密钥就好了。token里面包含userId跟tokenId,我们使用token
Openresty Redis正确使用连接池(set_keepalive)
ole_triangle_java的博客
12-30
1396
最近在做一个openresty项目,每次访问需要通过openresty读取redis,判断是否可以允许访问。
问题:
如果每次访问就要与redis建立连接,当并发量大时,连接数会直接爆炸。影响性能和系统。
方案一:
在init_by_lua中先创建redis连接,在access_by_lua中直接使用:
init.lua:
local redis = require "redis"
client = redis.connect('127.0.0.1', 6379)
filter.lua(演示
openresty 如何通过连接池方式连接访问设置密码的redis
xyw10000
03-12
5280
redisUtil.lua
local redis = require "resty/redis"
local log = ngx.log
local ERR = ngx.ERR
local setmetatable = setmetatable
local _M = {
local mt = { __index = _M }
local function errlog(......
Openresty最佳案例 | 第7篇: 模块开发、OpenResty连接Redis
热门推荐
方志朋的专栏
11-23
4万+
Lua模块开发在实际的开发过程中,不可能把所有的lua代码写在一个lua文件中,通常的做法将特定功能的放在一个lua文件中,即用lua模块开发。在lualib目录下,默认有以下的lua模块。lualib/
├── cjson.so
├── ngx
│ ├── balancer.lua
│ ├── ocsp.lua
│ ├── re.lua
│ ├── semaphore.lua
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
©️2022 CSDN
皮肤主题:编程工作室
设计师:CSDN官方博客
返回首页
一行Java
CSDN认证博客专家
CSDN认证企业博客
码龄12年
暂无认证
146
原创
2万+
周排名
4520
总排名
94万+
访问
等级
6753
积分
1313
粉丝
542
获赞
439
评论
3010
收藏
私信
关注
热门文章
MySQL安装及可视化工具使用
75444
基于Docker搭建redis集群
49050
LVS+KeepAlived+Nginx高可用实现方案
43582
MongoDB+MongoVUE安装及入门
39975
ApiPost 真香真强大,是时候丢掉 Postman、Swagger 了
37418
分类专栏
java 面试题
11篇
Java
17篇
开发工具
11篇
高效工具
11篇
Redis面试题
2篇
Spring Boot
11篇
虚拟机
2篇
JDK
1篇
JDK7
1篇
面试题
14篇
学习路线
1篇
数据库面试题
2篇
spring
1篇
消息队列
1篇
Spring面试题
2篇
SpringMVC面试题
1篇
SpringBoot面试题
3篇
Kafka
1篇
SpringCloud面试题
1篇
Spring Cloud
3篇
持续集成
2篇
git
3篇
Spring MVC
2篇
并发编程
1篇
apollo
1篇
JVM虚拟机
1篇
RPC
1篇
k8s漫漫学习路
移动开发
29篇
数据库
12篇
后端
33篇
Linux
6篇
加密
1篇
CPU卡
1篇
OpenResty
5篇
KeepAlived
1篇
Redis
6篇
ftp
1篇
SpringBoot
7篇
网络
4篇
Nginx
2篇
docker
9篇
SpringCloud
2篇
Maven
最新评论
复旦微电子CPU卡发卡流程
z_shen:
你好,这个传输认证(外部认证)的3des加密的可以用你的mac、tac校验文章里面的工具类么?
ApiPost 真香真强大,是时候丢掉 Postman、Swagger 了
jianhui00001:
国产的还是太花里花哨了,postman还是比这个好用多了
ApiPost 真香真强大,是时候丢掉 Postman、Swagger 了
weixin_45482260:
最近很多尬吹apipost的。尬吹最后接一个apipost得链接🔗。真是恶心🤢。
用 Long 做 Map 的 Key,存的对象花一下午才取出来,坑惨了
夜凉初醒:
菜鸟今天遇到类似的问题,学习了
ApiPost 真香真强大,是时候丢掉 Postman、Swagger 了
不穿格子衫的码农:
尬吹
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
阿里为何禁止在对象中使用基本数据类型
5年软件测试工程师感悟——写给还在迷茫的朋友
还在手动发包?手把手教你 Jenkins 自动化部署SpringBoot
2022年12篇
2021年28篇
2020年25篇
2019年40篇
2018年6篇
2017年8篇
2016年29篇
目录
目录
分类专栏
java 面试题
11篇
Java
17篇
开发工具
11篇
高效工具
11篇
Redis面试题
2篇
Spring Boot
11篇
虚拟机
2篇
JDK
1篇
JDK7
1篇
面试题
14篇
学习路线
1篇
数据库面试题
2篇
spring
1篇
消息队列
1篇
Spring面试题
2篇
SpringMVC面试题
1篇
SpringBoot面试题
3篇
Kafka
1篇
SpringCloud面试题
1篇
Spring Cloud
3篇
持续集成
2篇
git
3篇
Spring MVC
2篇
并发编程
1篇
apollo
1篇
JVM虚拟机
1篇
RPC
1篇
k8s漫漫学习路
移动开发
29篇
数据库
12篇
后端
33篇
Linux
6篇
加密
1篇
CPU卡
1篇
OpenResty
5篇
KeepAlived
1篇
Redis
6篇
ftp
1篇
SpringBoot
7篇
网络
4篇
Nginx
2篇
docker
9篇
SpringCloud
2篇
Maven
目录
评论 2
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
打赏作者
一行Java
你的鼓励将是我创作的最大动力
¥2
¥4
¥6
¥10
¥20
输入1-500的整数
余额支付
(余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付
您的余额不足,请更换扫码支付或充值
打赏作者
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值