Openresty Redis正确使用连接池(set_keepalive)

使用openResty搭建nginx分发层遇到set_keepalive报错问题解决 使用openResty搭建nginx分发层遇到set_keepalive报错问题解决 |[error] 24164#0: *462 lua entry thread aborted: runtime error: /usr/hello/lualib/resty/http.lua:909: bad argument #2 to ‘set_keepalive’ (number expected, go... 阅读详情

最近在做一个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(演示:简单的黑名单功能,如果request的remoteip在redis中存在key,就返回403):

client = red;

function redisHasKey(client,keyname)
	if(client:get(keyname))
	then
		return true;
	else
		return false;
	end
end

local keyname = ngx.var.remote_addr;
if(pcall(redisHasKey,client,keyname))then
	if(redisHasKey(client,keyname))
	then
		ngx.exit(403);
	else
		return
	end
else
	return
end

在nginx启动时,就创建了连接,并只使用这个连接。就不会出现连接数过多问题。

方案一问题:

1、在使用中redis故障会导致功能不可用,即使重启redis还需要重启nginx才能重新获取连接。

2、linux tcp连接不能保证长时间不中断。中断后不能修复。

3、单连接在高并发多请求情况下,会阻塞请求,多个请求会等待连接空闲后再进行操作,甚至直接报错。

方案二:

连接池,针对连接数管理

openresty官方本身有连接池管理(set_keepalve)

语法:syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size)

我就来试着用下,这次只使用filter.lua:

local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
red:set_keepalive(1000, 20)
red:connect("127.0.0.1", 6379)
client = red;

function redisHasKey(client,keyname)
	if(client:get(keyname))
	then
		return true;
	else
		return false;
	end
end

local keyname = ngx.var.remote_addr;
if(pcall(redisHasKey,client,keyname))then
	if(redisHasKey(client,keyname))
	then
		ngx.exit(403);
	else
		return
	end
else
	return
end

问题:

使用之后发现更大的问题,连接数量没有被连接池控制,同时出现大量报错:

2021/05/19 13:57:57 [error] 2734932#0: *2019 attempt to send data on a closed socket: u:00000000401F79D0, c:0000000000000000, ft:0 eof:0, client: 127.0.0.1, server: , request: "GET / HTTP/1.0", host: "127.0.0.1:8082"
2021/05/19 13:57:57 [error] 2734932#0: *2019 attempt to send data on a closed socket: u:00000000401F79D0, c:0000000000000000, ft:0 eof:0, client: 127.0.0.1, server: , request: "GET / HTTP/1.0", host: "127.0.0.1:8082"
2021/05/19 13:57:57 [alert] 2734932#0: *2019 socket() failed (24: Too many open files), client: 127.0.0.1, server: , request: "GET / HTTP/1.0", host: "127.0.0.1:8082"
2021/05/19 13:57:57 [error] 2734932#0: *2019 attempt to send data on a closed socket: u:00000000401F6290, c:0000000000000000, ft:0 eof:0, client: 127.0.0.1, server: , request: "GET / HTTP/1.0", host: "127.0.0.1:8082"

连接在被使用的时候已经中断了。

解决:

看下官方对于set_keepalive的用法说明:

set_keepalive

syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size)

Puts the current Redis connection immediately into the ngx_lua cosocket connection pool.

You can specify the max idle timeout (in ms) when the connection is in the pool and the maximal size of the pool every nginx worker process.

In case of success, returns 1. In case of errors, returns nil with a string describing the error.

Only call this method in the place you would have called the close method instead. Calling this method will immediately turn the current redis object into the closed state. Any subsequent operations other than connect() on the current object will return the closed error.

简单来说,set_keepalive使用时是用来替代close的,如果使用了set_keepalive之后再对连接进行任何除了connect的操作都会报错。

看来看官方文档很重要啊!

改进下:

local redis = require "resty.redis"
local red = redis:new()
--red:set_timeouts(1000, 1000, 1000)
--red:set_keepalive(1000, 20)
red:connect("127.0.0.1", 6379)
client = red;

function redisHasKey(client,keyname)
	if(client:get(keyname))
	then
		return true;
	else
		return false;
	end
end

local keyname = ngx.var.remote_addr;
if(pcall(redisHasKey,client,keyname))then
	if(redisHasKey(client,keyname))
	then
		red:set_keepalive(1000, 200)
		ngx.exit(403);
	else
		red:set_keepalive(1000, 200)
		return
	end
else
	red:set_keepalive(1000, 200)
	return
end

虽然用起来还挺恶心,但确实解决了我们的问题。

在使用ab测试时连接数虽然不会被严格控制在set_keepalive的pool_size数值内,但能够与测试的并发量相关。

Centos7 openresty使用Lua连接Redis集群(包括单机版redis) 1、新增 lua-resty-redis-cluster 模块 连接redis集群需要用到 lua-resty-redis-cluster模块 github地址: https://github.com/cuiweixie/lua-resty-redis-cluster 网盘:我的代码工程--》jar包--》lua-resty-redis-cluster-master 下载完成之后,只需要用到包中的2个文件rediscluster.lua和redis_slot.c 复制包中的 redis_sl... 阅读详情

相关推荐

Docker构建OpenResty+Lua+MySQL+Redis集群高性能网关实践

容器化技术通过将应用及其依赖打包成标准单元,实现了环境一致性与快速部署,是现代微服务架构的核心支撑。其原理基于操作系统级虚拟化,通过命名空间和控制组实现资源隔离与限制,为应用提供轻量级、可移植的运行环境。这一技术价值在于彻底解决了“开发环境与生产环境不一致”的经典难题,显著提升了软件交付效率与系统可靠性。在应用场景上,容器化尤其适用于需要复杂依赖管理、弹性伸缩和高密度部署的场景,例如微服务网关、API中间件和实时数据处理平台。本文聚焦于使用Docker容器化部署高性能OpenResty网关,并集成Lua脚本

weixin_34314962的博客 491

openresty 连接 redis

本文介绍了如何使用 OpenResty 库中的 resty.redis 模块来连接 Redis 数据库,并进行基本的读写操作,以及使用 pipeline 提高效率和性能。使用 resty.redis 模块连接 Redis 数据库非常简单,而使用 pipeline 可以进一步提高效率和性能。

JudithHuang的博客 1449

Docker容器化OpenResty+Lua+MySQL+Redis Cluster高性能Web后端环境实战

在现代Web应用架构中,容器化技术已成为实现环境一致性和快速部署的核心手段。Docker通过将应用及其依赖打包成标准化的镜像,从根本上解决了开发、测试和生产环境差异的难题。其原理基于操作系统级虚拟化,利用命名空间和控制组实现资源隔离,为微服务架构提供了轻量级、可移植的运行环境。这一技术的工程价值在于显著提升了开发效率、简化了CI/CD流程,并确保了应用在不同基础设施上行为的一致性。在构建高性能Web后端服务时,常需整合Nginx网关、业务逻辑处理层、数据库和缓存等多个组件。OpenResty通过将Lua虚拟

weixin_30924087的博客 668

OpenResty使用Lua大全(四)OpenResty中使用Redis

redis的连接是tcp连接,建立TCP连接需要三次握手,而释放TCP连接需要四次握手,而这些往返时延仅需要一次,但A,B业务共用了连接池,很有可能 B业务拿到的 A业务使用的连接,而此连接操作的数据库db1;如果当前连接不是从内建连接池中获取的,该方法总是返回 0 ,也就是说,该连接还没有被使用过。注意:我们如何知道,redis连接对象是从连接池中获取的,还是新创建的连接呢?以后应该复用TCP连接,此时就可以考虑使用连接池,即连接池可以复用连接。1、连接池是每Worker进程的,而不是每Server的;

秃了也弱了 3813

OpenResty高性能实践:Lua非阻塞操作Redis的完整指南

在Web开发与API网关架构中,缓存和状态管理是提升系统性能的核心技术。Redis作为高性能键值数据库,通过内存存储和丰富数据结构,为高并发场景提供快速数据访问能力。其非阻塞I/O模型与事件驱动架构相结合,能够有效支撑大规模并发请求。在OpenResty环境下,利用LuaJIT与Nginx深度集成的特性,通过lua-resty-redis客户端库实现非阻塞Redis操作,完美契合Nginx事件模型,避免阻塞worker进程。这种技术方案特别适用于需要低延迟响应的**API网关**和**实时数据处理**场景,

404

基于Canal与OpenResty Lua的电商广告缓存实时更新架构实践

在电商等高并发场景中,缓存是提升系统性能、保障用户体验的核心技术组件。其基本原理是将热点数据存储在内存中,减少对后端数据库的直接访问,从而显著降低响应延迟。传统定时轮询更新缓存的方式存在延迟高、数据库压力大等痛点。为解决此问题,业界引入了基于数据库日志变更捕获的技术方案,通过监听数据库的binlog实现数据变更的实时感知。这种事件驱动的架构将缓存更新逻辑与业务代码解耦,实现了对业务零侵入的精准同步。其中,Canal作为阿里巴巴开源的MySQL数据库增量日志解析组件,能够实时捕获数据变更事件;而OpenRes

weixin_34357887的博客 346

OpenResty 与 Lua 实现高效 Redis 连接池

在现代高性能 Web 应用程序中,Redis 作为一个高效的内存数据库,通常用于缓存、会话管理和实时数据分析等场景。然而,当使用 Redis 时,特别是在高并发的环境中,频繁的连接和断开 Redis 实例会消耗大量的系统资源并影响性能。因此,Redis 连接池的设计和实现显得尤为重要。本文将深入探讨如何在 OpenRest...

qq_35485206的博客 1133

Lua HTTP客户端库lua-resty-http从入门到精通:安装、请求、连接池与实战

HTTP协议是现代网络通信的基石,它定义了客户端与服务器之间请求与响应的标准格式,支撑着Web服务、API交互等核心互联网应用。其工作原理基于请求-响应模型,通过TCP连接传输数据,并利用状态码、头部和消息体来传递信息。在Lua生态中,由于标准库未内置网络功能,引入专门的HTTP客户端库成为实现网络通信的关键技术方案。lua-resty-http作为高性能的纯Lua实现,不仅解决了Lua进行HTTP调用的基础需求,其连接池复用机制和细粒度超时控制更显著提升了高并发场景下的程序性能与资源利用率。无论是调用RE

weixin_30932215的博客 376

基于OpenResty与Redis构建高性能动态IP黑白名单系统

在Web应用安全与运维领域,IP访问控制是保障服务稳定与数据安全的基础技术。其核心原理是通过识别客户端IP地址,基于预设规则决定是否允许访问,从而有效防御恶意爬虫、CC攻击等威胁。传统静态配置方式存在更新繁琐、影响服务等局限,而结合Nginx OpenResty的Lua扩展能力与Redis高性能内存数据库,可实现动态、集中化的名单管理。该方案的技术价值在于将访问控制逻辑从配置文件中解耦,支持实时热更新与策略一致性分发,大幅提升了运维效率与系统安全性。典型的应用场景包括保护管理后台、API接口限流、以及自动封

weixin_30843605的博客 325

Nginx集成客户端指纹实现访问控制:OpenResty实战指南

在Web安全与精细化运营领域,访问控制是保障应用安全的核心机制。其原理是通过识别请求来源,基于预设规则决定是否允许访问,从而防止恶意请求与资源滥用。这项技术的价值在于为后端服务构建高效的前置防线,显著提升系统安全性与稳定性。典型的应用场景包括金融交易反欺诈、社交平台反爬虫、内容平台防刷量等高频风控需求。本文聚焦于将客户端指纹这一前沿设备识别技术,与高性能Web服务器Nginx相结合,通过OpenResty的Lua扩展能力,实现基于传感器数据等多维特征的实时访问控制与流量治理。

weixin_33701617的博客 413

OpenResty高性能Web平台开发指南

OpenResty作为基于Nginx与LuaJIT的高性能Web平台,通过将Nginx的事件驱动架构与Lua脚本语言的灵活性相结合,实现了高效的Web应用开发。其核心原理在于利用LuaJIT解释器执行接近原生代码效率的Lua脚本,并通过ngx_lua模块嵌入到Nginx请求处理流程中。这种架构显著提升了Web服务的性能,减少了反向代理与后端服务间的网络开销,同时提高了开发效率。在应用场景上,OpenResty特别适合API网关、实时日志处理和边缘计算等高并发、低延迟需求的场景。通过合理配置连接池、缓存策略和

weixin_30699955的博客 295

OpenResty与Redis高性能集成:Lua协程操作缓存与原子脚本实践

缓存是提升Web应用性能的核心技术,通过在内存中存储热点数据,减少数据库访问,从而显著降低响应延迟。其原理基于局部性原理,利用内存的高速读写特性。在技术实现上,Nginx作为高性能Web服务器,通过反向代理和负载均衡处理海量并发,而Redis作为内存数据结构存储,提供丰富的数据类型和原子操作。将两者结合,OpenResty通过内嵌LuaJIT引擎,允许在Nginx处理阶段直接执行Lua脚本操作Redis,实现了架构扁平化。这种技术组合的价值在于减少了网络跳转和序列化开销,特别适用于高并发场景如秒杀、实时计数

weixin_30654583的博客 320

OpenResty技术栈解析与高性能Web开发实践

OpenResty作为基于Nginx与LuaJIT的高性能Web平台,通过事件驱动模型和LuaJIT即时编译技术,实现了非阻塞式动态网关处理能力。其核心原理在于利用epoll/kqueue的I/O多路复用机制,结合Lua脚本的高效执行,使单线程可处理数万并发连接。在技术价值方面,OpenResty不仅提升了Web服务的性能,还通过模块化架构支持动态路由、负载均衡、边缘计算等场景。典型应用包括API网关实现、请求内容实时改写和安全防护等。通过cosocket和共享内存等特性,开发者可以构建高性能的微服务架构和

weixin_30607659的博客 304

OpenResty网关层集成Redis实战:从环境搭建到生产级Lua脚本开发

在现代高并发应用架构中,网关层作为流量入口,其性能与扩展性至关重要。Nginx以其高效的反向代理和静态资源处理能力著称,但当需要在请求处理链路中引入动态业务逻辑时,其原生配置便显局限。OpenResty通过在Nginx核心中嵌入LuaJIT虚拟机,赋予了网关层动态执行复杂逻辑的能力,实现了从静态配置到可编程网关的演进。结合Redis这一高性能内存数据存储,其极致的读写速度和丰富的数据结构,为缓存、会话管理和实时计数等场景提供了理想方案。将两者结合,能在网关层直接完成令牌校验、库存扣减、API限流等操作,在微

weixin_33851429的博客 338

学习利用ce修改游戏生命参数

易语言代码 游戏的简陋界面 用ce查找存储这个1000即生命值的内存地址(得先附加到目标程序上,点击左上角那个电脑按钮) 看到有很多值为1000的,但哪个是生命值呢?真相只有一个 我们点击一下打我这个按钮,看下面的ce界面上地址为004A65C0处的值变了,所以这个就是我们要找的生命值 接下来我们对生命值进行修改,修改为99

zsd747289639的博客 5万+

第一篇:常见CAN错误帧及其排查方向

在本文中主要阐述各类错误帧的形成原因以及在使用同星硬件设备出现错误帧时,应当 如何进行排查并消除错误帧。在 CAN 总线通信中,通常遇见的错误帧主要为以下五种,其 分别是:bit error、ACK error、stuff error、CRC error 以及 form error。

u013089100的博客 1746

OpenResty实战:基于Nginx+Lua构建高性能动态API网关

在Web架构中,Nginx作为高性能的反向代理和负载均衡器,其静态配置模式在处理复杂业务逻辑时存在局限。通过引入Lua脚本引擎,OpenResty扩展了Nginx的能力边界,使其能够在请求处理的生命周期中动态执行逻辑。这项技术的核心价值在于将轻量级业务逻辑前置到网关层,实现高并发、低延迟的处理,同时保持架构的简洁性。其典型应用场景包括动态鉴权、API聚合、实时限流和配置热更新等。本文以构建动态API网关为例,详细阐述了如何利用OpenResty的**鉴权**和**限流**模块,在Nginx的访问控制和内容生

weixin_33910460的博客 407

银河麒麟V10系统下,手把手解决Ollama安装报错‘GLIBCXX_3.4.25 not found’

本文详细介绍了在银河麒麟V10系统下解决Ollama安装报错‘GLIBCXX_3.4.25 not found’的实战指南。通过隔离编译新版libstdc++、环境变量引导和服务化封装等安全方案,确保在不破坏系统稳定性的前提下顺利运行Ollama,适用于国产操作系统与AI工具的兼容性需求。

weixin_42556197的博客 484

openresty 如何通过连接池方式连接访问设置密码的redis

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(......

xyw10000 5918

ChatGPT and Claude国内使用站点

这篇博客介绍了不同的AI聊天平台和定价信息,主要对比了ChatGPT和Claude两款产品。文章列出了多个提供聊天服务的AI平台,包括RawChat、ChatGPTPlus、ChatOpens、Wildcard和2233.ai等,并提供了每个平台的网页链接和定价详情。特别关注了Claude平台,介绍了其普通账号与会员账号的不同,以及相关的定价信息。此外,还提到了一些虚拟卡定价和服务细节,为用户选择合适的AI服务提供了多种参考。

nisidjndn的博客 1万+

Rk3128投影仪救砖操作和固件分享思路

大家搞一条比较硬的东西,插入耳机口,就可以进入刷机模式了的,我的机器是这样的,大家也可以试试。(看不懂可以往下看)

MMX7088的博客 1万+

openresty mysql_openresty 学习笔记四:连接mysql和进行相关操作

毕竟redis是作为缓存,供程序的快速读写,虽然reidis也可以做持久化保存,但还是需要一个做数据存储的数据库。比如首次查询数据在redis查询不到则查询mysql,再将查询结果写过redis供下次查询。保存数据也可以先写入redis再通过队列使用另外的程序异步写入mysql。后面会逐步把openresty写入rabbitmq和python通过订阅rabbitmq的队列将数据写入mysql得方法...

weixin_31972679的博客 414

YOLOv11涨点改进 | 全网创新首发、主干改进篇 | CVPR 2025 | RAVLT主干让 YOLOv11 更加强大!通过增强线性注意力机制,特别在小目标和复杂背景的检测上表现突出

本文提出RAVLT主干网络,通过改进YOLOv11的空间特征建模能力,显著提升小物体和复杂背景检测性能。RAVLT采用秩增强线性注意力(RALA)机制,在保持线性计算复杂度的同时解决传统线性注意力低秩问题。RALA通过增强KV缓冲区和输出特征矩阵的秩,提高特征多样性和建模能力。实验表明,RAVLT在ImageNet-1k上达到84.4% Top-1准确率,仅需2600万参数和4.6GFLOPs,性能优于现有线性注意力模型。文章详细介绍了RAVLT模块结构、实现原理及在YOLOv11中的集成方法,包含四种主干

Ai缝合怪、助力小伙伴高效发论文 641

让我直接涨薪5K的Nginx/OpenResty详解,NginxLua操作Redis有多牛

以上代码处于nginx-redis-demo.conf文件中,修改后需要重启OpenRestry,然后可以使用浏览器访问其地址/pool_demo,具体的访问结果如图8-22所示。总之,作为一个专业的服务端开发工程师,大家必须要对连接池有较深理解,其实不论是Redis连接池、HTTP连接池,还是数据库连接池,甚至是线程池,其原理都是差不多的。②坑:如果设置错误,那么red连接对象不一定可用,不能把可用性存疑的连接放回池子里,如果另一个请求从连接池获取到一个不能用的连接,就会直接报错。

m0_63437643的博客 439

【产品经理修炼之道】-如何搭建企业级账务系统?

笔者公司的业务模式具有一定的独特性,不同于我们常见的市面上供应链类公司的进销存模式。公司主要为各大银行和金融机构提供信贷领域的风控服务,客户主要通过请求公司的数据产品接口产生费用,可以简单地理解为请求一次接口收费0.5元,一个月若是有1w人请求同一个接口则公司需要收费5000元。

xiaoli8748的专栏 5408

一文掌握DrissionPage的详细使用

是一个基于 Python 的网页自动化工具,主要用于网页数据的抓取、自动化操作和测试。它结合了 Selenium 和 Requests 的优点,提供了更简洁、高效的 API,适用于各种网页自动化任务。DrissionPage 是一个功能强大且易于使用的网页自动化工具,适用于各种网页自动化任务。希望本文的 DrissionPage 的基本使用方法和一些高级功能能够帮助到你。

数据知道的博客 1万+
上一篇: Nginx(OpenResty)+Lua+Redis IP限流 10s内
下一篇: java SXSSF 导出excel 合并单元格,设置打印分页
ole_triangle_java
博客等级 码龄10年 82粉丝 83原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值