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

news2024/12/29 9:02:16

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 ...] timeout
  summary: Remove and get the first element in a list, or block until one is available
  since: 2.0.0

  BRPOP key [key ...] timeout
  summary: Remove and get the last element in a list, or block until one is available
  since: 2.0.0

  BRPOPLPUSH source destination timeout
  summary: Pop a value from a list, push it to another list and return it; or block until one is available
  since: 2.2.0

  BLPOP key [key ...] timeout
  summary: Remove and get the first element in a list, or block until one is available
  since: 2.0.0

  BRPOP key [key ...] timeout
  summary: Remove and get the last element in a list, or block until one is available
  since: 2.0.0


  LLEN key
  summary: Get the length of a list
  since: 1.0.0

  LPOP key
  summary: Remove and get the first element in a list
  since: 1.0.0

  LPUSH key value [value ...]
  summary: Prepend one or multiple values to a list
  since: 1.0.0

  LPUSHX key value
  summary: Prepend a value to a list, only if the list exists
  since: 2.2.0

  RPOP key
  summary: Remove and get the last element in a list
  since: 1.0.0

  RPOPLPUSH source destination
  summary: Remove the last element in a list, prepend it to another list and return it
  since: 1.2.0

  RPUSH key value [value ...]
  summary: Append one or multiple values to a list
  since: 1.0.0

  RPUSHX key value
  summary: Append a value to a list, only if the list exists
  since: 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 patterns
  since: 2.0.0

  PUBLISH channel message
  summary: Post a message to a channel
  since: 2.0.0

  PUBSUB subcommand [argument [argument ...]]
  summary: Inspect the state of the Pub/Sub subsystem
  since: 2.8.0

  PUNSUBSCRIBE [pattern [pattern ...]]
  summary: Stop listening for messages posted to channels matching the given patterns
  since: 2.0.0

  SUBSCRIBE channel [channel ...]
  summary: Listen for messages published to the given channels
  since: 2.0.0

  UNSUBSCRIBE [channel [channel ...]]
  summary: Stop listening for messages posted to the given channels
  since: 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命令特点:

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

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

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

相关文章

怎么把heic改成jpg?方法大全在这里

怎么把heic改成jpg?HEIC是一种现代的图像文件格式。它是由ISO制定的标准,并得到了苹果公司的支持和推广。与JPG等传统图像格式相比,HEIC格式可以提供更好的图像质量,并且占用更少的存储空间。这使得它在手机、平板电脑和其他移动设…

Java中在循环体内拼接字符串时为什么使用StringBuilder而不是String

在循环体内拼接字符串时为什么使用StringBuilder而不是String 在《阿里巴巴Java开发手册》一书中提到了: 循环体内,字符串的连接方式,请使用 StringBuilder 的 append 方法进行扩展。(而不要用String的方式) 说明&…

解决IP地址欺骗的网络安全策略

随着互联网的不断发展,网络安全已经成为企业和个人关注的重要问题。其中,IP地址欺骗是一种常见的威胁,它可能导致数据泄露、身份伪装和网络攻击。 1. 使用防火墙和入侵检测系统 防火墙和入侵检测系统(IDS)是网络安全…

Sui的动态可组合NFT为Cosmocadia增加游戏趣味性

的新游戏Cosmocadia展示了Sui NFT如何在游戏中四处走动,种植和收获蔬菜,并在工作台上制作工具和家具。未来将更新利用NFT,如私人土地,甚至让玩家将他们的SuiFrens NFT带入游戏中。 Lucky Kat Studios的产品经理Bente Bolland将Co…

神奇的代码恢复工具

文章目录 概述工具展示工具下载地址运行过程附件待恢复代码 概述 小C是一名程序猿,他有好多新奇的点子,也乐于把这些变成文字分享给大家。这些分享大部分都与代码相关,在文章里面把这些代码全部按本来的结构展示出来也不是一件容易的事&…

LMI FocalSpec 3D线共焦传感器 使用笔记1

一.硬件介绍 以上特别注意: 屏蔽线必须接地,因为在现场实际调试中,使用软件调试发现经常 弹窗 传感器丢失警告!! 以上 Position LED 的灯被钣金挡住,无法查看异常现象,能否将指示灯设置在软件界面上? 需要确认是软触发还是硬触发,理论上 硬触发比软触发速度要快.(我们目前使用…

Zilliz X Dify.AI ,快速打造知识库 AI 应用

Zilliz 大模型生态矩阵再迎新伙伴!近日,Zilliz 和 Dify.AI 达成合作,Zilliz 旗下的产品 Zilliz Cloud、Milvus 与开源 LLMOps 平台 Dify 社区版进行了深度集成。 01.Zilliz Cloud v.s. Dify Dify 作为开源的 LLMs App 技术栈,在此…

[GXYCTF2019]BabyUpload - 文件上传+绕过(后缀文件类型文件内容.htaccess)

[GXYCTF2019]BabyUpload 解题流程 解题流程 1、上传一句话,提示“后缀不允许ph” 2、修改后缀为jpg,提示“上传类型也太露骨了吧!” 3、修改类型为image/jpeg,提示“诶,别蒙我啊,这标志明显还是php啊” 4、…

【Axure教程】将figma导入Axure

Figma和Axure是两个不同的界面设计工具,Figma主要用于创建和协作设计图形界面(UI),允许多个设计师和利益相关者同时在云端协作设计项目;Axure是原型设计工具,专注于创建高保真、可交互的原型。大家可以根据…

Java学习笔记(一)——概述

目录 一、Java概述 (一)Java技术体系平台 (二)Java重要特点 (三)Java运行机制及运行过程 (四)JDK (五)JRE 二、Java的快速入门 (一&#…

掌握Python机器学习:空间模拟与时间预测的实战指南

了解全文点击:《掌握Python机器学习:空间模拟与时间预测的实战指南》 文章目录 一、机器学习原理与概述二、Python编译工具组合安装教程三、掌握Python语法及常见科学计算方法四、机器学习数据清洗五、机器学习与深度学习方法六、机器学习空间模拟实践操作七、机器…

6数据层相关框架-基本

MyBatis常见面试问题,以及和hibernate 的区别等_mybatis和hiberbate区别面试_my_styles的博客-CSDN博客*1、什么是MyBatis?*答:MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。*2、讲下MyBatis的缓存*答:MyBatis的…

实现即时沟通与协作的全功能IM即时通讯系统

在当今竞争激烈的商业环境中,高效的沟通和协作成为企业取得成功的关键。在过去,电子邮件和电话等传统工具是企业之间进行沟通和协作的重要手段,然而,随着科技的发展和社交化的趋势,IM即时通讯系统正逐渐成为企业协作的…

虹科方案 | 虹科ATTO 4K/8K以太网解决方案

一、方案背景 以太网为中小型媒体制作工作室提供经济高效的共享存储解决方案。尽管 10GbE 继续在 4K 工作流程中发挥重要作用,但 8K 等新格式需要额外的带宽。 为了使您的环境适应未来的新制作格式,需要一种更强大、低延迟的连接技术,一种足…

外卖点餐小程序源码 扫码点餐小程序源码

外卖点餐小程序源码 扫码点餐小程序源码 吃饭点外卖,坐车靠窗边,睡觉侧着身,洗澡要放歌,随时随地要自拍.......这些俨然早已成为我们当代新青年的真实生活写照。 近年来外卖行业蓬勃发展,外卖小哥走街串巷&#xff0…

FastAPI学习-26 并发 async / await

前言 有关路径操作函数的 async def 语法以及异步代码、并发和并行的一些背景知识 async 和 await 关键字 如果你正在使用第三方库,它们会告诉你使用 await 关键字来调用它们,就像这样: results await some_library()然后,通…

竞赛 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 人脸识别系统 该项目…

JVM第三讲:JVM 基础-字节码的增强技术详解

JVM 基础-字节码的增强技术详解 本文是JVM第三讲,JVM 基础-字节码的增强技术。在上文中,着重介绍了字节码的结构,这为我们了解字节码增强技术的实现打下了基础。字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术…

CV计算机视觉每日开源代码Paper with code速览-2023.10.12

精华置顶 墙裂推荐!小白如何1个月系统学习CV核心知识:链接 点击CV计算机视觉,关注更多CV干货 论文已打包,点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【目标检测】A Novel Voronoi-based Convolutional Neura…

二叉树题目:二叉树寻路

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:二叉树寻路 出处:1104. 二叉树寻路 难度 5 级 题目描述 要求 在一个无限的二叉树上,每个结点都有两个子结点,结…