openresty lua用Redis的Stream解决消息订阅问题

使用 Redis Streams 解决消息订阅和消费的问题,可以避免在订阅模式下的连接管理问题。下面是如何使用 OpenResty 和 Redis Streams 实现类似的功能。

配置 nginx.conf

确保你的 nginx.conf 文件中配置了 Lua 模块和 Redis 集群的连接信息:

http {lua_shared_dict redis_cluster_slot_locks 10m;lua_shared_dict redis_cluster_slot_cache 10m;init_worker_by_lua_file /path/to/init_worker.lua;server {listen 8080;location /publish {content_by_lua_block {local redis_cluster = require "resty.rediscluster"local config = {name = "testCluster",serv_list = {{ ip = "127.0.0.1", port = 7000 },{ ip = "127.0.0.1", port = 7001 },{ ip = "127.0.0.1", port = 7002 },{ ip = "127.0.0.1", port = 7003 },{ ip = "127.0.0.1", port = 7004 },{ ip = "127.0.0.1", port = 7005 }},keepalive_timeout = 60000,keepalive_cons = 1000,connection_timout = 1000,max_redirection = 5}local red = redis_cluster:new(config)local res, err = red:xadd("mystream", "*", "message", "Hello, World!")if not res thenngx.say("failed to publish: ", err)returnendngx.say("message published to stream mystream")local ok, err = red:set_keepalive(10000, 100)if not ok thenngx.say("failed to set keepalive: ", err)returnend}}}
}

init_worker.lua

init_worker.lua 中编写消费逻辑,并确保在消费模式下正确管理连接:

local redis_cluster = require "resty.rediscluster"
local config = {name = "testCluster",serv_list = {{ ip = "127.0.0.1", port = 7000 },{ ip = "127.0.0.1", port = 7001 },{ ip = "127.0.0.1", port = 7002 },{ ip = "127.0.0.1", port = 7003 },{ ip = "127.0.0.1", port = 7004 },{ ip = "127.0.0.1", port = 7005 }},keepalive_timeout = 60000,keepalive_cons = 1000,connection_timout = 1000,max_redirection = 5
}local function consume_stream(premature)if premature thenreturnendlocal red = redis_cluster:new(config)local last_id = "0"  -- 开始读取的起始 IDwhile true dolocal res, err = red:xread("COUNT", 10, "BLOCK", 1000, "STREAMS", "mystream", last_id)if not res thenngx.log(ngx.ERR, "failed to read stream: ", err)breakendif res and res[2] thenfor _, stream in ipairs(res[2]) dofor _, message in ipairs(stream[2]) dolocal id = message[1]local fields = message[2]ngx.log(ngx.INFO, "received message: ", fields[2])last_id = idendendendendred:close()-- Schedule another stream consumption attemptlocal ok, err = ngx.timer.at(1, consume_stream)if not ok thenngx.log(ngx.ERR, "failed to create timer: ", err)end
end-- Schedule the consume_stream function
local ok, err = ngx.timer.at(0, consume_stream)
if not ok thenngx.log(ngx.ERR, "failed to create timer: ", err)
end

关键点解释

  1. 避免在消费模式下调用 set_keepalive

    • 在消费模式下,我们不会尝试将连接放入连接池,而是直接读取消息并处理。
  2. 连接管理

    • 消费操作在 consume_stream 函数内进行。
    • 在读取失败时,记录错误并退出循环,然后释放连接。
  3. 使用 ngx.timer.at 调度消费函数

    • 使用 ngx.timer.at(0, consume_stream) 调度消费函数,以便在 worker 初始化时立即开始消费。
  4. 处理 Redis Streams

    • 使用 xread 命令读取流中的消息。
    • 通过循环读取消息并处理。

测试

  1. 启动 OpenResty 并配置上述 nginx.confinit_worker.lua

  2. 使用发布接口发布消息,查看 OpenResty 日志确认消息已接收:

    curl "http://localhost:8080/publish"
    

    在 OpenResty 日志中应该看到类似如下输出:

    2024/07/09 16:04:00 [info] 12345#0: *1 [lua] init_worker.lua:23: received message: Hello, World!
    

通过这些配置和代码,你可以在 OpenResty 中使用 Redis Streams 实现对消息的长期消费,并正确处理连接的生命周期和错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

暑假学习DevEco Studio第一天

学习目标: 掌握构建第一个ArkTS应用 学习内容: 容器的应用 创建流程 点击file,new-> create project 点击empty ->next 进入配置界面 点击finsh,生成下面图片 这里需要注意记住index.ets ,这是显示页面 –…

五款免费可视化利器分享,助力打造数字孪生新体验!

在当今数据驱动的时代,可视化工具已成为各行各业不可或缺的助手。它们不仅能帮助我们更好地理解和分析数据,还能以直观、生动的方式呈现复杂信息,提升沟通和决策效率。本文将为大家介绍五款免费的可视化工具,总有一款适合你。 一…

selenium 获取请求头cookie信息

在做接口测试如登陆接口过于复杂,可以先使用UI自动化把cookie保存在本地供接口测试使用 import time from selenium import webdriver from selenium.webdriver.chrome.options import Optionsdef get_seeion():# 创建Chrome浏览器的Options对象chrome_options Op…

如何做好企业品牌推广,看这篇文章就够了

在当今竞争激烈的市场环境中,品牌推广策略与方式成为企业成功的关键。因为相比起企业,消费者会更愿意为品牌买单。那么企业如何将品牌推广做好呢?今日投媒网与您分享。 1.明确品牌定位与目标受众 一切推广活动的起点在于清晰的品牌定位。首先&#xf…

苹果ios安卓apk应用APP文件怎么修改手机APP显示的名称

当我们安装了一款 APP后,该 APP的名称可能就是我们看到的名称,那么我们可以通过修改手机 APP显示的名称来修改该 APP文件的名称,那么具体怎么操作呢?下面就给大家来介绍一下。 首先我们进入手机上的应用商店,然后在搜…

SolrCloud Autoscaling 自动添加副本

SolrCloud Autoscaling 自动添加副本 前言 问题描述 起因是这样的,我在本地调试 Solr 源码(版本 7.7.3),用 IDEA 以 solrcloud 方式启动了 2 个 Solr 服务,如下所示: 上图的启动参数 VM Options 如下&am…

RocketMQ实战:一键在docker中搭建rocketmq和doshboard环境

在本篇博客中,我们将详细介绍如何在 Docker 环境中一键部署 RocketMQ 和其 Dashboard。这个过程基于一个预配置的 Docker Compose 文件,使得部署变得简单高效。 项目介绍 该项目提供了一套 Docker Compose 配置,用于快速部署 RocketMQ 及其…

美国商超入驻细节全面曝光,电竞外设产品的国际化浪潮即将席卷全球

近年来,随着电子竞技(简称电竞)行业的蓬勃发展,电竞外设产品也逐渐成为消费者关注的热点。近期,一系列美国商超入驻细节的全面曝光,预示着电竞外设产品的出海风潮即将到来。 电竞行业迅速崛起,全球市场规模年均增长超1…

ResNet50V2

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 一、ResNetV1和ResNetV2的区别 ResNetV2 和 ResNetV1 都是深度残差网络(ResNet)的变体,它们的主要区别在于残差块的设计和…

Spring Security在企业级应用中的应用

Spring Security在企业级应用中的应用 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在企业级应用中应用Spring Security,这是保…

美业系统实操:手机App如何查看员工业绩?美业门店管理系统Java源码分享

在当今竞争激烈的美业市场中,有效的管理对于提高效率、增强客户体验和推动业务增长至关重要。美业管理系统通过其各种功能和优势,成为现代美业企业不可或缺的利器。 ▶下面以博弈美业进行实操-手机App端如何查看员工业绩? 1.店主登录手机端…

不是大厂云用不起,而是五洛云更有性价比

明月代维的一个客户的大厂云境外云服务器再有几天就到期了,续费提醒那是提前一周准时到来,但是看到客户发来的续费价格截图,我是真的没忍住。这不就是在杀熟吗?就这配置续费竟然如此昂贵?说实话这个客户的服务器代维是…

关于vue3的一些前端面试题

1.ref() 响应式对象顶级响应式对象,可以在模板中直接使用不用添加 .value,可以直接使用ref() 对像更新,Vue会自动检测更新,然后更新Dom深层次的对象也可以是响应式,也会被追踪shallowRef() 是ref的浅层次表现,深层次的…

Ollama+OpenWeb UI搭建最简单的大模型交互界面

Open WebUI是一个专为大型语言模型(LLMs)设计的Web用户界面。这个界面提供了一个直观、响应迅速且易于使用的平台,使用户能够与本地运行的语言模型进行交互,就像与云服务中的模型交互一样。可以非常方便的调试、调用本地模型。你能…

贴片电阻:01A、01B、01C、01D分别是什么意思?

贴片电阻的识别方法: 1、数字索位标称法 (一般矩形片状电阻采用这种标称法) 数字索位标称法就是在电阻体上用三位数字来标明其阻值。它的第一位和第二位为有效数字,第三位表示在有效数字后面所加“0”的个数.这一位不会出现字母。例如&…

测试开发面试题和答案

Python 请解释Python中的列表推导式(List Comprehension)是什么,并给出一个示例。 答案: 列表推导式是Python中一种简洁的构建列表的方法。它允许从一个已存在的列表创建新列表,同时应用一个表达式来修改或选择元素。…

项目实战-MySQL极佳优化方案---前缀索引

一、应用背景 由于公司项目数据量较大,开发小程序和APP过程中,SQL查询超过1.5s以上的等待时间,因此需要对SQL或者数据表结构设计进行优化。就不讲SQL语句优化啦,而是记录一下数据表结构设计优化的前缀索引实现。 二、MySQL索引 …

python学习-基础1

一.简介 Python的特点和优势是什么? Python是一种解释型语言、动态类型语言、面向对象编程语言,具有丰富的库和广泛的应用领域。 python大小写敏感,靠缩进保证代码的执行 二.Python中的数据类型 Python的八种数据类型八种数据类型分别是…

昇思25天学习打卡营第10天|使用静态图加速

昇思25天学习打卡营第10天|使用静态图加速 前言使用静态图加速背景介绍动态图模式静态图模式 静态图模式的使用场景静态图模式开启方式基于装饰器的开启方式基于context的开启方式 静态图的语法约束JitConfig配置选项静态图高级编程技巧 个人任务打卡(读者请忽略&am…

UE4_材质_水体的反射与折射制作_Ben教程

在这个教程中,将制作水的反射和折射,上个教程,我们主要讲了制作水涟漪(水面波纹)和水滴法线混合,水深计算,我们首先要谈的是反射和产生折射的问题。我们将所有从干扰从场景中分离出去&#xff0…