当前位置: 首页 > news >正文

Redis实现简易消息队列的三种方式

Redis实现简易消息队列的三种方式

消息队列简介

消息队列是一种用于在计算机系统中传递和处理数据的重要工具。如果你完全不了解消息队列,不用担心,我将尽力以简单明了的方式来解释它。

首先,想象一下你正在玩一个游戏,而游戏中有很多任务需要完成,但你不需要立刻完成它们。相反,你可以将这些任务列在一个清单上,然后按照你的时间表逐个完成。消息队列就像这个任务清单一样,只不过它用于计算机程序之间传递任务和数据。

消息队列的基本原理是,一个程序可以将一条消息(或任务)发送到队列中,然后另一个程序可以从队列中取出并处理这条消息。这种方式有几个关键优点:

  1. 异步通信:消息队列允许程序之间进行异步通信,也就是说,发送消息的程序不需要等待接收消息的程序立刻响应,它们可以继续执行其他任务。

  2. 解耦合:消息队列有助于解耦合(解除程序之间的依赖关系)。发送消息的程序不需要知道哪个程序将接收消息,而接收消息的程序只需要关注如何处理消息,而不需要担心消息的来源。

  3. 缓冲和负载均衡:消息队列可以用作缓冲区,帮助应对高负载情况。如果一个程序在某个时刻发送了大量消息,接收消息的程序可以按照自己的速度处理这些消息,而不会因为消息过多而崩溃。

  4. 数据持久化:有些消息队列系统还具有数据持久化功能,这意味着消息不会丢失,即使系统发生故障,消息也可以在恢复后重新处理。

  5. 可伸缩性:消息队列是构建分布式系统的重要工具,因为它们可以帮助应对不断增长的负载,而无需重新设计整个系统。

最常见的消息队列系统之一是RabbitMQ、Apache Kafka和Amazon SQS等。它们在不同情境下有不同的应用,但基本原理是相似的:它们都允许程序之间以异步、松散耦合的方式交换信息,从而提高系统的可伸缩性、可靠性和性能。

总之,消息队列是一种非常有用的工具,用于在计算机系统中传递和处理数据,帮助程序更高效地协同工作,提供了许多优点,包括异步通信、解耦合、缓冲、数据持久化和可伸缩性。希望这个简单的解释能帮助你理解消息队列的基本概念。

什么是消息队列:字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色:

  • 消息队列:存储和管理消息,也被称为消息代理(Message Broker)
  • 生产者:发送消息到消息队列
  • 消费者:从消息队列获取消息并处理消息

Redis消息队列-基于List实现消息队列

消息队列(Message Queue),字面意思就是存放消息的队列。而Redis的list数据结构是一个双向链表,很容易模拟出队列效果。

队列是入口和出口不在一边,因此我们可以利用:LPUSH 结合 RPOP、或者 RPUSH 结合 LPOP来实现。
不过要注意的是,当队列中没有消息时RPOP或LPOP操作会返回null,并不像JVM的阻塞队列那样会阻塞并等待消息。因此这里应该使用BRPOP或者BLPOP来实现阻塞效果。

关于redis list的操作说明:

BLPOP key [key ...] timeoutsummary: Remove and get the first element in a list, or block until one is availablesince: 2.0.0BRPOP key [key ...] timeoutsummary: Remove and get the last element in a list, or block until one is availablesince: 2.0.0BRPOPLPUSH source destination timeoutsummary: Pop a value from a list, push it to another list and return it; or block until one is availablesince: 2.2.0BLPOP key [key ...] timeoutsummary: Remove and get the first element in a list, or block until one is availablesince: 2.0.0BRPOP key [key ...] timeoutsummary: Remove and get the last element in a list, or block until one is availablesince: 2.0.0LLEN keysummary: Get the length of a listsince: 1.0.0LPOP keysummary: Remove and get the first element in a listsince: 1.0.0LPUSH key value [value ...]summary: Prepend one or multiple values to a listsince: 1.0.0LPUSHX key valuesummary: Prepend a value to a list, only if the list existssince: 2.2.0RPOP keysummary: Remove and get the last element in a listsince: 1.0.0RPOPLPUSH source destinationsummary: Remove the last element in a list, prepend it to another list and return itsince: 1.2.0RPUSH key value [value ...]summary: Append one or multiple values to a listsince: 1.0.0RPUSHX key valuesummary: Append a value to a list, only if the list existssince: 2.2.0

更多详细内容通过命令

help @list

查看

通过list的演示代码

127.0.0.1:6379> rpush list1 1 2 3 
(integer) 3
127.0.0.1:6379> lpop list1
"1"
127.0.0.1:6379> lpop list1
"2"
127.0.0.1:6379> lpop list1
"3"

阻塞演示:

一个生产者,两个消费者

在这里插入图片描述

让两个消费者获取消息

brpop list 123  

此时两个消费者都进入阻塞模式

在这里插入图片描述

现在生产消息

lpush list test

结果:

在这里插入图片描述

从图中可以看出,生产者进行了两次生产,消费者只能一个一个的获取消息。

基于List的消息队列有哪些优缺点?
优点:

  • 利用Redis存储,不受限于JVM内存上限
  • 基于Redis的持久化机制,数据安全性有保证
  • 可以满足消息有序性

缺点:

  • 无法避免消息丢失 (生产者处理消息时丢失,而在List中已经被删除)
  • 只支持单消费者

Redis 消息队列-基于PubSub的消息队列

PubSub(发布订阅)是Redis2.0版本引入的消息传递模型。顾名思义,消费者可以订阅一个或多个channel,生产者向对应channel发送消息后,所有订阅者都能收到相关消息。

SUBSCRIBE channel [channel] :订阅一个或多个频道
PUBLISH channel msg :向一个频道发送消息
PSUBSCRIBE pattern[pattern] :订阅与pattern格式匹配的所有频道

使用简介:

 PSUBSCRIBE pattern [pattern ...]summary: Listen for messages published to channels matching the given patternssince: 2.0.0PUBLISH channel messagesummary: Post a message to a channelsince: 2.0.0PUBSUB subcommand [argument [argument ...]]summary: Inspect the state of the Pub/Sub subsystemsince: 2.8.0PUNSUBSCRIBE [pattern [pattern ...]]summary: Stop listening for messages posted to channels matching the given patternssince: 2.0.0SUBSCRIBE channel [channel ...]summary: Listen for messages published to the given channelssince: 2.0.0UNSUBSCRIBE [channel [channel ...]]summary: Stop listening for messages posted to the given channelssince: 2.0.0

使用结果

在这里插入图片描述

基于PubSub的消息队列有哪些优缺点?
优点:

  • 采用发布订阅模型,支持多生产、多消费

缺点:

  • 不支持数据持久化
  • 无法避免消息丢失
  • 消息堆积有上限,超出时数据丢失

Redis 消息队列-基于Stream的消息队列

下面是添加消息的方法,其中key是指定stream的关键字,id是唯一的,如果输入*的话由redis自动生成,然后就是添加field string,键值对了

XADD key ID field string [field string ...]
summary: Appends a new entry to a stream
since: 5.0.0

下面是读消息的方法,其中COUNT可选字段表示读几条消息,BLOCK表示阻塞读取,其中的milliseconds如果为0表示永久,STREAMS就表示你要看的stream的key是什么,然后就是ID了,ID有两个选项一个0表示读取第一条消息$表示读取最新消息,但是这个读取最新消息可能会出现漏读现象。

XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
summary: Return never seen elements in multiple streams, with IDs greater than the ones reported by the caller for each stream. Can block.
since: 5.0.0

在这里插入图片描述

两个消费者同时进入阻塞读取最新消息

在这里插入图片描述

可以看到两个同时读取到了

在这里插入图片描述

新增多条消息,只能收取到最新消息

在这里插入图片描述

STREAM类型消息队列的XREAD命令特点:

优点:

  • 消息可回溯
  • 一个消息可以被多个消费者读取
  • 可以阻塞读取

缺点:

  • 有消息漏读的风险

消费者组解决漏读问题

消费者组(Consumer Group):将多个消费者划分到一个组中,监听同一个队列。具备下列特点:

  • 消息分流
    • 队列中的消息会分流给组内的不同消费者,而不是重复消费,从而加快消息处理的速度
  • 消息标示
    • 消费者组会维护一个标示,记录最后一个被处理的消息,哪怕消费者宕机重启,还会从标示之后读取消息。确保每一个消息都会被消费
  • 消息确认
    • 消费者获取消息后,消息处于pending状态,并存入一个pending-list。当处理完成后需要通过XACK来确认消息,标记消息为已处理,才会从pending-List移除。

创建消费者组

XGROUP CREATE key groupName ID [MKSTREAM]
  • key : 队列名称
  • groupName: 消费者组名称
  • ID: 起始ID标示 , $代表队列中最后一个消息,0则代表队列中第一个消息
  • MKSTREAM: 队列不存在时自动创建队列

删除指定的消费者组

XGROUP DESTORY key groupName

给指定的消费者组添加消费者(一般自动添加)

XGROUP CREATECONSUMER key groupName consumername

删除消费者组中的指定消费者

XGROUP DELCONSUMER key groupname consumername		

从消费者组读取消息

XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ……] ID [ID ……]
  • group : 消费者组名
  • consumer:消费者名称,如果消费者不存在,会自动创建一个消费者
  • count : 本次查询的最大数量
  • BLICK milliseconds: 当没有消息时最长等待时间
  • NOACK: 无需手动ACK(ACK确认消息,从pending-list中移除),胡渠道消息后自动确认
  • STREAMS key : 指定队列名称
  • ID : 获取雄安锡的起始ID
    • > : 从下一个未消费的消息开始
    • 其他:根据指定id从pending-list中获取已消费单位确认的消息,例如0,从pending-list中的第一个消息开始。

确认消息

 XACK key group ID [ID ...]
  • key : stream 名称
  • group : 消费者组名称
  • id: 就是消息的ID

查看pending-list中的消息信息

XPENDING key group [start end count] [consumer]
  • key: stream 名称

  • group : group 名称

  • start end count : 可以使用 - 代表从第一个 +代表对后一个这两个配合就是所有,然后用count表示出几个,示例

    xpending stream1 g1 - + 10
    

在java中的逻辑

在这里插入图片描述

STREAM类型消息队列的XREADGROUP命令特点:

  • 消息可回溯
  • 可以多消费者争抢消息,加快消费速度
  • 可以阻塞读取
  • 没有消息漏读的风险
  • 有消息确认机制,保证消息至少被消费一次

相关文章:

Redis实现简易消息队列的三种方式

Redis实现简易消息队列的三种方式 消息队列简介 消息队列是一种用于在计算机系统中传递和处理数据的重要工具。如果你完全不了解消息队列,不用担心,我将尽力以简单明了的方式来解释它。 首先,想象一下你正在玩一个游戏,而游戏中…...

基于SpringBoot的在线小说阅读平台系统

基于SpringBoot的在线小说阅读平台系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 个人中心 登录界面 管理员界面 摘要 基于Spring Boot的在线小说阅读…...

VMware Workstation 与 Hyper-V 不兼容。请先从系统中移除 Hyper-V 角色

引用地址...

uniapp h5 MD5加密

文章目录 1.当使用 CryptoJS 进行 MD5 加密时,你需要先引入 CryptoJS 库并确保它已经正确安装。下面是一个更详细的示例代码:2.然后,在需要使用 MD5 加密的地方,引入 CryptoJS 代码库:3.接下来,我们定义一个…...

2023_Spark_实验十八:安装FinalShell

下载安装包 链接:https://pan.baidu.com/s/14cOJDcezzuwUYowPsOA-sg?pwd6htc 提取码:6htc 下载文件名称:FinalShell.zip 二、安装 三、启动FinalShell 四、连接远程 linux 服务器 先确保linux系统已经开启,不然连接不上 左边…...

文件服务器管理服务器怎么设置

文件服务器是一种提供文件存储和共享服务的服务器,它可以方便企业内部的员工共享文件,提高工作效率。为了更好地管理和维护文件服务器,需要对其进行合理的设置。下面小编将介绍文件服务器管理服务器的基本设置方法。 一、选择合适的操作系统 …...

LeetCode每日一题——Single Number

文章目录 一、题目二、题解 一、题目 136. Single Number Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. You must implement a solution with a linear runtime complexity and use only constant extra …...

有什么手机软件能分离人声和音乐?

很多人在制作混剪视频,需要二次创作的时候,就经常会把人声分离、背景音乐伴奏提取出来,然后重新加入自己的创意跟想法。下面就一起来看看如何用手机软件分离人声和音乐的吧! 音分轨 一款可以分离人声和背景音乐的手机软件&#x…...

私人服务器可以干嘛

目录 搭建个人网站或博客: 远程桌面: 作为网盘储存: 作为测试和学习环境: 推广产品: 游戏私服(注意,仅限于个人自己单机玩): 个人服务器可以用于多种用途,以下是一些常见的用途:…...

【EI会议征稿】第三届高性能计算与通信工程国际学术会议(HPCCE 2023)

第三届高性能计算与通信工程国际学术会议(HPCCE 2023) 第三届高性能计算与通信工程国际学术会议(HPCCE 2023)将于2023年12月22-24日在长沙召开。HPCCE 2023将围绕“高性能计算与通信工程”的最新研究领域,为来自国内外高等院校、科学研究所、…...

项目管理,如何做到流程标准化?

在PMP管理学习规范化、标准化和流程化的背景下,我们在日常工作中会遇到各种大小不一的工作项目。为了能够确保项目按时高质量地完成,项目管理变得至关重要。项目管理可以简单地解释为,在给定的时间和资源限制下,通过协调有限资源&…...

windows编译ollvm笔记

准备工作 1.找到Android SDK目录配置好cmake环境变量 E:\AndroidSDK\cmake\3.18.1(E:\AndroidSDK为 Android SDK目录地址)。 下载llvm-mingw编译环境(gcc编译器的windows版本,即可以在windows平台上使用gcc编译器),下载地址&…...

问:TCP/IP协议栈在内核态的好还是用户态的好

“TCP/IP协议栈到底是内核态的好还是用户态的好?” 问题的根源在于,干嘛非要这么刻意地去区分什么内核态和用户态。 引子 为了不让本文成为干巴巴的说教,在文章开头,我以一个实例分析开始。 最近一段时间,我几乎每…...

JavaScript-Vue基础语法-创建-组件-路由

文章目录 1.创建vue项目1.1.自定义创建项目1.2.项目结构解析1.3.主要文件1.4.其它 2.项目运行3.Vue组件概念3.1.组件基础概念3.2.单文件组件三要素3.3.组件注册3.4.组件通信 4.Vue路由概念4.1.简单使用4.2.路由参数4.3.嵌套路由4.4.路由导航4.5.代码导航4.6.路由守卫 5.总结 HT…...

前端开发中的 TypeScript 泛型:深入解析

前端开发中的 TypeScript 泛型:深入解析 TypeScript(简称 TS)是一种由微软开发的强类型超集 JavaScript 语言,它为前端开发者提供了更严格的类型检查和更强大的工具支持。其中,泛型是 TypeScript 中的一个强大概念&am…...

06-spring的beanFactoryPostProcessor的执行

文章目录 1. 接口BeanFactoryPostProcessor1.1 英文说明及要点2. BeanDefinitionRegistryPostProcessor3. 执行逻辑4. 几个重要实现类1. 接口BeanFactoryPostProcessor 1.1 英文说明及要点 Factory hook that allows for custom modification of an application context’s b…...

想要精通算法和SQL的成长之路 - 分割数组的最大值

想要精通算法和SQL的成长之路 - 分割数组的最大值 前言一. 分割数组的最大值1.1 二分法 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 分割数组的最大值 原题链接 首先面对这个题目,我们可以捕获几个关键词: 非负整数。非空连续子数组。 那么我…...

【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】

【深度学习】【Opencv】【GPU】python/C调用onnx模型【基础】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【Opencv】【GPU】python/C调用onnx模型【基础】前言Python版本OpenCVWindows平台安装OpenCVopencv调用onnx模型 C版本…...

Oracle update 关联更新优化方法

关联更新顾名思义就是指,更新的数据从关联的表中获取并update到目标表。并且该SQL将会是一个天然的嵌套循环。有两种优化思路解决: 1、PLSQL 根据rowid更新 是否需要加order by rowid的考量: 如果buffer cache足够大,能够放得下要…...

USB协议学习(一)帧格式以及协议抓取

USB协议学习(一)帧格式以及协议抓取 笔者来聊聊MPU的理解 这里写自定义目录标题 USB协议学习(一)帧格式以及协议抓取MPU的概念以及作用MPU的配置新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式…...

前端工程化知识系列(8)

目录 71.你有经验使用TypeScript或Flow等类型检查工具来提高前端代码的可维护性和质量吗?72. 如何处理前端应用的搜索引擎优化(SEO)问题,特别是在单页面应用(SPA)中?73. 你了解渐进式Web应用&am…...

UnrealEngine iOS 打包 —— 签名证书(cer、p12)生成

官方文档 docs.unrealengine.com/5.3/zh-CN/setting-up-ios-tvos-and-ipados-provisioning-profiles-and-signing-certificates-for-unreal-engine-projects 打开 ProjectSettings -> Platforms -> iOS 可以看到签名证书配置 需要拓展名为 .cer 和 .p12 的一对证书和密钥…...

【广州华锐互动】VR高层火灾应急疏散演练提供一种无风险的逃生体验

在科技进步的今天,我们已经能够利用虚拟现实(VR)技术来模拟各种紧急情况,其中就包括高楼火灾逃生。VR高层火灾应急疏散演练系统是一种新兴的技术,它使用虚拟现实环境来模拟高楼火灾的实际情况,为人们提供一…...

定档通知2024中国(上海)国际品牌叉车展览会

时 间:2024年7月24~26日 地 点:上海国家会展中心 ◆ 》》》展会概况: 叉车在“搬运设备”中扮演着非常重要的角色,是机械化装卸、堆垛和短距离运输的高效设备。近年来,在“节能环保&#xff0c…...

Ubuntu编译安装colmap遇到的几个问题以及解决

总体安装过程已经很明白了,写的人很多了,我就不赘述了,可以参考这里或者其他博客。我主要记录几个我遇到的问题以及解决方法。 1、cmake报错:No CMAKE_CUDA_COMPILER could be found. 这个原因是没找到cuda和nvcc目录&#xff0…...

【Qt上位机】打开本地表格文件并获取其中全部数据

前言 其实本文所实现的功能并非博主要实现的全部功能,只是全部功能中的一小部分,这里只是为了记录一下实现方法,防止后续忘记,仅供参考。 文章目录 一、实现效果二、UI设计三、程序设计3.1 选择本地表格文件3.2 获取表格总行列数3…...

香港服务器选纯国际线路上网稳定吗?

​  关于香港服务器的线路,我们平时接触较多的分三大类,即纯国际线路、回国专线和香港本地线路。三者价格上存有差距,原因体现在线路和网络质量上,当然这些会关系到服务器的速度和稳定性。譬如,有些用户在选择了纯国…...

USB PD3.1

目前我们大多数Type-C接口仍然采用的是PD3.0快充协议,按当前用户的使用场景来看功率也完全够用,那么PD3.1快充协议是什么?USB PD3.1到底有没有必要? 不妨我们先了解一下PD3.1: 5月25日,USB-IF协会推出了USB Type-C线…...

unity面试八股文 - 基础篇

委托是什么? event 关键字有什么用? 委托: 委托是一种特殊类型的对象,它包含了对一个方法的引用。简单来说,委托就像是一个安全的函数指针。它允许我们创建可在运行时动态更改其引用方法的变量,并且可以指向类中定义…...

构建高效问题解答平台:使用Cpolar和Tipas在Ubuntu上搭建专属问答网站

文章目录 前言2.Tipask网站搭建2.1 Tipask网站下载和安装2.2 Tipask网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道(云端设置)3.3 Cpolar稳定隧道(本地设置) 4. 公网访问测试5. 结语 前…...

个人网页设计师/长沙百度快速优化排名

Ⅰ、概述 打开上一篇文章新建的工程,是提取的ST标准库里面源代码文件和UCOS工程包源代码文件。下载过的朋友可能会知道,直接编译那个工程会有大片的错误和警告,原因在于那个工程是没有经过修改源代码的工程,接下来就是讲述一步一步…...

wordpress禁用修订/免费友情链接交换平台

云计算职业转型之一:企业架构师 企业架构师在技术和各平台上是一个颇为具有代表性的角色,但那些准备转移至云的企业寻找的是有那些特定技术的员工。 请看下面的职业图表。有两条非常好的途径可供选择:公共云解决方案架构师和安全架构师。大…...

宁波企业做网站哪家好/英文网站seo

问题现象: 请一段开发个项目 程序调试全部通过但测试时出现个问题 “out of memory” 在长时间运行时!后来终于解决 :很简单其实就是object.create时对象没有释放。 代码如下: function SplitString(const Source,ch:string):TStr…...

大连网站建设个人/站长工具whois查询

原标题:用Python打造一款文件搜索工具,所有功能自己定义!一、前言大家好,又到了Python办公自动化系列。在日常的办公中,我们经常会从一堆不同格式的文件(夹)中搜索特定的文件,可能你是凭着记忆去找或是借助…...

wordpress为什么放弃/怎么让关键词快速排名首页

关于C,hanoi塔的递归问题一直是个经典问题,我们学习数据结构的时候也会时常用到, 因为它的时间复杂度和空间复杂度都很高,我们在实际的应用中不推荐使用这种算法,移动n个盘子, 需要2的n次幂减一步&#xff…...

报名网站如何做/中国腾讯和联通

phpredis是php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系很有用;以下是redis官方提供的命令使用技巧:下载地址如下:https://github.com/owlient/phpredis(支持redis 2.0.4)Redis::__construct…...