redis实现消息队列
背景
消息队列(Message Queue)是一种常见的软件架构模式,用于在分布式系统中传递和处理异步消息。它解耦了发送消息的应用程序和接收消息的应用程序之间的直接依赖关系,使得消息的发送者和接收者可以独立地演化和扩展。
消息队列的基本原理是发送者将消息发送到一个中间代理(即消息队列),然后接收者从该中间代理中消费消息。中间代理充当了消息的缓冲区,确保消息的可靠传递和持久化存储(根据需要),同时提供了高吞吐量、低延迟和可伸缩性。

相信在做分布式服务开发的时候,或多或少的使用到了消息队列,如主流的kafka、 rocketMQ。总结下来,消息队列的优点包括:
- 异步通信:发送者和接收者之间的解耦,使得它们可以独立地操作和演化,无需实时等待回应。
- 应用解耦:消息队列使不同的应用程序能够以独立的方式进行开发、部署和伸缩,降低了系统之间的耦合度。
- 削峰填谷:消息队列可以作为缓冲区,处理突发的请求和高峰期的流量,从而减轻系统的压力。
- 消息持久化:消息队列可以将消息持久化存储,确保在异常情况下不会丢失消息。
- 可靠性和扩展性:消息队列提供了高可靠性和可伸缩性,通过多个消费者处理大量的消息。
总而言之,消息队列是一种强大的软件架构模式,通过解耦应用程序之间的依赖关系,提供了高可靠性、高吞吐量和可伸缩性的消息传递机制。它在构建分布式系统、处理异步任务和解决系统耦合等方面发挥着重要作用。
那今天的案例呢,没有使用到kafka rocketMQ, 而是继续我的专题redis。
redis实现消息队列
list
list这种数据结构天然的支持消息队列,常用的命令如下:
| 命令 | 描述 |
|---|---|
| LPUSH key value | 在列表头部插入一个或多个值 |
| RPUSH key value | 在列表尾部插入一个或多个值 |
| LPOP key | 弹出并返回列表头部的一个值 |
| RPOP key | 弹出并返回列表尾部的一个值 |
| LRANGE key start stop | 获取列表中指定范围内的所有值 |
| LLEN key | 获取列表的长度 |

好的,这个shigen用Java的代码实现以下:
- 创建消息队列服务类
redisMessageQueueService

主要的是三个方法,发送数据、消费数据和判断消息队列是否为空。
- 消息处理类
messProcessor

这个类或者说是组件主要是处理消息,这里简单的在控制台输出打印。
- 系统的接口
messageQueueController

其实就是通过接口的方式调用messageQueueServie,实现消息的发送和接受消费。
那最终的效果是什么样的呢》我本地使用的是curl进行的进一步的测试。
list实现的方式测试效果:

最后,总结一下list实现消息队列的优缺点:
优点:
- 简单易用:Redis的List数据结构操作简单,易于理解和使用。
- 支持多样化操作:List数据结构提供了丰富的操作方法,如插入、删除、获取范围等。
缺点:
消息队列的设计最重要的就是消息的防丢失问题。
- 缺乏消息确认机制:List方式没有内置的消息确认机制,当消费者处理消息失败或发生异常时,消息可能会丢失。
- 不支持消息持久化:Redis的List数据结构默认存储在内存中,当Redis重启或宕机时,消息也会丢失。
- 不适合高并发场景:在高并发情况下,List方式可能存在性能问题,因为LPUSH和BRPOP是单线程操作,无法充分利用多核CPU的优势。
- 不适合多订阅者。现在的list是一对一的模式,不支持一对多的模式。
pub/sub模式
针对list一对一的模式,pub/sub可以实现一对多的模式。

常见的redis操作命令如下:
| 命令 | 描述 |
|---|---|
| PUBLISH channel message | 将消息 message 发送到指定的频道 channel |
| SUBSCRIBE channel [channel …] | 订阅一个或多个频道,接收这些频道中发布的消息 |
| UNSUBSCRIBE [channel [channel …]] | 取消订阅一个或多个频道 |
| PSUBSCRIBE pattern [pattern …] | 订阅一个或多个符合给定模式的频道 |
| PUNSUBSCRIBE [pattern [pattern …]] | 取消订阅一个或多个符合给定模式的频道 |
| PUBSUB subcommand [argument [argument …]] | 获取关于 Redis Pub/Sub 状态的信息 |
我们在控制台测试一下:

那具体的代码如何实现呢?这里依旧选取的是Java代码作为案例的设计。
- 定义消息发布的接口并实现发送消息的操作
MessagePublisherImpl

- 消息订阅者
messageSubscriberImpl

- 配置类中加上
redisMessageListenerContainer的bean

- controller测试

服务运行,接口测试一下:

订阅多个topic的话,这样设置:
container.addMessageListener(messageListener, new PatternTopic("pub_channel"));
// 监听多个topic
container.addMessageListener(messageListener, new PatternTopic("pub_channel1"));
ok,貌似这种方式也显得很nice,至少比list的实现方式更nice,那它能解决实际的问题吗?我们总结一下这种方式的优缺点:
优点:
- 实现了多个消费者订阅同一个topic
缺点
-
数据不可靠:Redis 的 pub/sub 模式没有任何持久化机制,如果发布的消息在订阅者还没有收到前发生宕机,那么这些消息将会丢失。因此,如果需要确保数据的可靠性和持久化,需要使用 Redis 的其他数据结构或者使用 Redis 的 AOF 或 RDB 持久化机制。
-
消息不能防止重复消费:Redis 的 pub/sub 模式不支持消息的确认和回调机制,因此,当订阅者收到消息时,无法对其进行确认,也就无法防止重复消费
那有什么好的解决方式呢?stream应需求而生。
stream
Redis 的 Stream 是一个基于时间序列的数据结构,用于存储和处理消息。Stream 可以看作是一个由消息组成的日志,每个消息都有一个唯一的 ID(可以是时间戳或其他方式生成),并且可以对消息进行按照时间的顺序和优先级进行排序。
Stream 可以支持多个消费者,并且可以保证每个消费者只能消费一次。Stream 还可以在一个组内进行消费者间负载均衡,以提高系统的可扩展性和高可用性。
常用的API如下:
| API | 描述 |
|---|---|
| XADD | 向指定的 Stream 中添加一个条目(消息)XADD key ID field string [field string …] |
| XDEL | 从指定的 Stream 中删除一个或多个条目 |
| XRANGE | 获取指定范围内的条目 |
| XREVRANGE | 获取指定范围内的逆序条目 |
| XLEN | 获取 Stream 中的条目数量 |
| XREAD | 从一个或多个 Stream 中读取待处理的条目 |
| XGROUP | 创建、管理和操作消费者组 |
| XACK | 确认一个或多个已处理的条目 |
| XCLAIM | 批量方式对待处理的条目进行声明和处理 |
| XPENDING | 获取待处理的条目信息 |
| XTRIM | 删除指定范围之外的条目 |
| XINFO | 获取 Stream 的相关信息 |
参考文章:基于Redis的Stream类型的完美消息队列解决方案
添加和读取消息的命令测试如下:

shigen在敲命令的时候也觉得很繁琐,有点麻烦,还是期待Java代码的api去操作消息队列。
参考文章:redis灵魂拷问:如何使用stream实现消息队列 如何在Springboot中使用Redis5的Stream
- 定义生产消息的
messageProcuder

主要是用来实现消息的发送
- 消息的接受
messageReceiver
实现了消息的ack

- 测试接口

测试中发现了如下错误:

使用stream并不适合用jedis作为连接池。因为我之前的案例都是基于jedis的,在这里果断的放弃了。
好了,以上就是《redis实现消息队列》的全部内容了。
与shigen一起,每天不一样!
相关文章:
redis实现消息队列
背景 消息队列(Message Queue)是一种常见的软件架构模式,用于在分布式系统中传递和处理异步消息。它解耦了发送消息的应用程序和接收消息的应用程序之间的直接依赖关系,使得消息的发送者和接收者可以独立地演化和扩展。 消息队列…...
JVM指令集
概述 JVM,Java Virtual Machine,Java虚拟机器,作为一台独立的机器,一般包括独立的指令集、独立的存储体系以及适合机器自身的运算方式,本章节主要是描述JVM指令的功能与作用。 JVM的每个指令的格式是【指令 操作数1操…...
如何用SSH克隆GitHub项目
诸神缄默不语-个人CSDN博文目录 使用场景:由于不可知的网络问题,无法用HTTPS克隆GitHub项目。 报错fatal: unable to access https://github.com/PolarisRisingWar/llm-throught-ages.git/: GnuTLS recv error (-110): The TLS connection was non-pro…...
sqlx库使用指南
sqlx库使用指南 在项目中我们通常可能会使用database/sql连接MySQL数据库。本文借助使用sqlx实现批量插入数据的例子,介绍了sqlx中可能被你忽视了的sqlx.In和DB.NamedExec方法。 sqlx介绍 在项目中我们通常可能会使用database/sql连接MySQL数据库。sqlx可以认为是Go…...
算法篇汇总
文章浏览 I https://leetcode.cn/problems/article-views-i/description/?envTypestudy-plan-v2&envId30-days-of-pandas&langpythondata 我的题解: import pandas as pddef article_views(views: pd.DataFrame) -> pd.DataFrame:dfviews[views[auth…...
typeScript 学习笔记(二)
类接口 TypeScript 入门教程 (xcatliu.com) 十四.类 ① 类 类:定义了一件事物的抽象特点,包含它的属性和方法对象:类的实例,通过new生成面向对象(OOP)的三大特性:封装、继承、多态封装&…...
redis集群架构详解
一、集群架构搭建 1、配置 在一台机器上模拟多台机器搭建redis集群,一个集群代表一台物理机 集群1路径: /usr/local/redis/redis-cluster/cluster1/9001/redis.conf/usr/local/redis/redis-cluster/cluster1/9004/redis.conf/usr/local/redis/redis-…...
nodejs设置镜像
1、npm镜像地址配置 -- 查看 npm 安装目录 npm root -g-- 查看 npm 配置信息 npm config list-- 查询当前镜像配置 npm get registry-- 或者仅修改 npm 命令镜像 -- 设置为淘宝镜像 npm config set registry https://registry.npmmirror.com -- 修改为官方镜像 npm config set…...
CSS中如何在table中隐藏表格中从第4个开始的多个 <tr> 元素
隐藏指定行 使用 CSS 的 nth-child 选择器来选择表格中的特定行,并隐藏它们。 以下是一个示例 CSS 规则,用于隐藏表格中的第 4 个和第 5 个行(索引从 1 开始): table tr:nth-child(4), table tr:nth-child(5) {displ…...
【类和对象】③友元类
文章目录 1.初始化列表2.static静态成员3.友元 1.初始化列表 我们知道在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。虽然调用构造函数之后,对象中已经有了一个初始值,但是不能将其称为对对象中成…...
算法通关村第十六关:黄金挑战:滑动窗口与堆结合
黄金挑战:滑动窗口与堆结合 堆的大小一般是有限的,能直接返回当前位置下的最大值或者最小值 该特征与滑动窗口结合,可以解决一些特定场景的问题 1. 滑动窗口与堆问题的结合 LeetCode239 https://leetcode.cn/problems/sliding-window-maxi…...
6.2.2 【MySQL】InnoDB中的索引方案
上边之所以称为一个简易的索引方案,是因为我们为了在根据主键值进行查找时使用二分法快速定位具体的目录项而假设所有目录项都可以在物理存储器上连续存储,但是这样做有几个问题: InnoDB 是使用页来作为管理存储空间的基本单位,也…...
划片机实现装片、对准、切割、清洗到卸片的自动化操作
划片机是一种用于切割和分离材料的设备,通常用于光学和医疗、IC、QFN、DFN、半导体集成电路、GPP/LED氮化镓等芯片分立器件、LED封装、光通讯器件、声表器件、MEMS等行业。划片机可以实现从装片、对准、切割、清洗到卸片的自动化操作。 以下是划片机实现这些操作的步…...
OpenCV(二十五):边缘检测(一)
目录 1.边缘检测原理 2.Sobel算子边缘检测 3.Scharr算子边缘检测 4.两种算子的生成getDerivKernels() 1.边缘检测原理 其原理是基于图像中灰度值的变化来捕捉图像中的边界和轮廓。梯度则表示了图像中像素强度变化的强弱和方向。 所以沿梯度方向找到有最大梯度值的像素&…...
上行取消指示 DCI format 2_4
上篇介绍了DCI format 2_1的DL传输中断的内容,这篇就看下DCI format 2_4有关的UL 传输取消机制,值得注意的是这里的UL传输针对的是PUSCH和SRS传输。 UL cancellation DCI format 2_4相关机制引入的背景与DCI format 2_1一样,都是因为URLLC和e…...
百望云蝉联2023「Cloud 100 China 」榜单 综合实力再获认可
9月7日,2023 Cloud 100 China 榜单于上海中心正式发布,榜单由靖亚资本与崔牛会联合推出,百望云凭借着过硬的综合实力与卓越的技术创新能力,再次荣登榜单,位居第六位。 本届评选,Top 100 企业的数据指标的权…...
力扣刷题班第1节:Python语法常遗漏的知识
以下仅仅记录和后面力扣刷题相关的、且平常会遗漏的语法知识。 下面这些笔记都是点到为止,不进行深入解释。大多数学过python的朋友看到就知道什么意思的,我就不解释了 字符串 str "I am a cook"# 按照空格切分 str.split(" ") …...
GET 和 POST请求的区别是什么
GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。 你轻轻松松的给出了一个“标准答案”: GET在浏览器回退时是无害的…...
Python数据分析实战-表连接-merge四种连接方式用法(附源码和实现效果)
实现功能 表连接-merge四种连接方式用法, 将两个pandas表根据一个或者多个键(列)值进行连接。 实现代码 import pandas as pddf1 pd.DataFrame({key: [a, b, d],data1: range(3)}) print(df1)df2 pd.DataFrame({key: [a, b, c, a, b],dat…...
NFTScan 浏览器再升级:优质数据服务新体验来袭
当前,高质量的 NFT 数据服务已成为区块链用户和开发者的必需。为满足用户数据需求,NFTScan 主站近日进行全面升级,优化了数据服务板块的页面结构,实现更清晰简洁的布局和交互。 NFTScan 的改版充分考虑用户和开发者的数据体验&am…...
ubuntu系统检测内核配置是否支持Docker核心模块
有一些内核缺少 Docker 所需的核心模块(overlayfs、bridge、iptables 相关等)所以在安装docker之前可以先检查一下。 脚本,可以检测Kernel配置是否符合Docker的运行要求 源地址:https://github.com/moby/moby/blob/master/contr…...
3分钟快速上手:免费高效的Elasticsearch可视化工具Elasticvue终极指南
3分钟快速上手:免费高效的Elasticsearch可视化工具Elasticvue终极指南 【免费下载链接】elasticvue Elasticsearch gui for the browser 项目地址: https://gitcode.com/gh_mirrors/el/elasticvue 你是否曾经为复杂的Elasticsearch集群管理而烦恼?…...
爆款AI写教材工具登场!一键生成低查重教材,轻松开启编写之旅
编写教材的困境与AI的解决方案 在编写教材时,如何准确地满足多样化的需求呢?不同年级的学生在认知能力上存在显著差异,教材内容若过于深奥或过于简单都无法达到效果;而课堂教学和自主学习等不同的环境对教材的要求各不相同&#…...
IDEA 2023.3 配置 JavaWeb 项目完整流程:从新建到打包 War 的保姆级避坑指南
IDEA 2023.3 配置 JavaWeb 项目完整流程:从新建到打包 War 的保姆级避坑指南 作为一名长期使用 IntelliJ IDEA 进行 JavaWeb 开发的工程师,我深知在配置项目时可能遇到的各种"坑"。特别是对于刚接触 IDEA 的新手来说,从项目创建到最…...
深入解析NAND Flash基础操作与系统集成——从阵列结构到多Die协同
1. NAND Flash基础结构与工作原理 NAND Flash存储器是现代存储系统的核心组件,从U盘到企业级SSD都依赖这项技术。要理解它的强大之处,得先从它的物理结构说起——想象一个巨大的立体停车场,每个停车位就是一个存储单元,而控制电路…...
MySQL服务启动失败:NET HELPMSG 3534错误全面解析与实战解决方案
1. 遇到NET HELPMSG 3534错误时该怎么办 当你兴致勃勃地安装完MySQL,准备大干一场时,突然在命令行输入net start mysql后,屏幕上跳出"MySQL服务无法启动。服务没有报告任何错误。请键入NET HELPMSG 3534以获得更多的帮助"这样的提…...
Unity引擎开发过的VR大场景项目网络技术,资源处理及热更新方案的报价大概多少
根据最新的市场招标数据、行业报价案例和技术方案分析,针对VR大场景项目的网络技术、资源处理、热更新方案三大模块的报价,整理如下:一、网络技术方案报价 网络技术方案主要解决多人在线同步、远程渲染、低延迟通信等问题。方案类型技术选型报…...
python基于微信小程序的直播带货商品数据分析系统的爬虫可视化
目录需求分析与系统架构设计微信小程序数据爬取方案数据存储与清洗数据分析与可视化系统集成与部署注意事项项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作需求分析与系统架构设计 明确系统目标为爬取微信小程序直播带货商品数…...
白城腾讯广告服务商
在白城,有不少企业想借助腾讯广告拓展业务,这就离不开靠谱的腾讯广告服务商。今天就和大家聊聊白城腾讯广告服务商的那些事儿,长春中网互联技术在这一领域表现就相当不错。白城腾讯广告服务商现状行业报告显示,近几年白城地区对腾…...
新书推荐:《尊严的颓败》在废墟之上,寻找灵魂的微光
当世界沦为巨大的名利场,当人被简化为数据与欲望的载体,我们该如何定义“人”?又该如何安放那颗被称为“灵魂”的种子?洛本的《尊严的颓败》并非一本让人阅读时感到轻松愉悦的书,它更像是一把手术刀,精准地…...
