Redis 消息队列笔记:List 与 Pub/Sub 📅 发布时间:2026/7/5 9:22:37 👁️ 浏览次数: 一、为什么实现消息队列消息队列的核心作用是把“生产消息”和“处理消息”分开。例如订单业务用户下单 ↓ 生产者把订单任务放入 Redis ↓ 消费者从 Redis 中取出订单任务 ↓ 异步创建数据库订单这样可以实现削峰高并发请求先进入 Redis数据库慢慢处理。异步用户不必等待全部业务执行完毕。解耦生产者只负责发送任务消费者只负责处理任务。多实例共享多个应用可以使用同一个 Redis 队列。Redis 中常见的消息通信方式包括List竞争消费适合简单任务队列。 Pub/Sub广播消费适合实时通知。 Stream更可靠适合订单、秒杀等重要业务。二、Redis List 实现消息队列1. List 的基本思想Redis List 是一个有顺序的双端列表可以从左边或右边放入、取出元素。最常见的队列组合生产者RPUSH 消费者BLPOP逻辑如下左边 右边 ← BLPOP [消息1消息2消息3] RPUSH →生产者从右边加入消息消费者从左边取消息因此满足先进先出。先进入的消息通常先被处理。这就是 FIFOFirst In First Out先进先出。2. List 常用命令命令作用LPUSH key value从左边加入元素RPUSH key value从右边加入元素LPOP key从左边取出并删除元素RPOP key从右边取出并删除元素BLPOP key timeout从左边阻塞获取元素BRPOP key timeout从右边阻塞获取元素LRANGE key 0 -1查看 List 全部内容DEL key删除 List3. 最简单的 List 队列假设订单队列名称为order.queue生产者发送订单消息RPUSH order.queue order-1001 RPUSH order.queue order-1002 RPUSH order.queue order-1003此时逻辑结构为左边 右边 [ order-1001 , order-1002 , order-1003 ]查看全部消息LRANGE order.queue 0 -1结果类似1) order-1001 2) order-1002 3) order-1003消费者取出一条消息LPOP order.queue得到order-1001此时队列变成[ order-1002 , order-1003 ]注意LPOP 不只是读取消息而是取出并删除消息。4. 为什么实际消费通常用 BLPOP如果队列为空LPOP order.queue会返回(nil)如果消费者一直循环执行LPOPLPOP 没有消息 LPOP 没有消息 LPOP 没有消息这叫轮询会不断访问 Redis浪费 CPU 和 Redis 资源。因此实际消费者通常使用阻塞命令BLPOP order.queue 0含义如果队列有消息立即取出一条。 如果队列为空当前客户端阻塞等待。 0 表示永不超时一直等待。它类似 Java 中orderTasks.take();对应关系Java BlockingQueueRedis Listput(message)RPUSH queue messagetake()BLPOP queue 0poll()LPOP queue5. 多消费者竞争消费可以开多个终端分别作为不同消费者。终端 A生产者 终端 B消费者 c1 终端 C消费者 c2消费者 c1BLPOP order.queue 0消费者 c2BLPOP order.queue 0生产者发送消息RPUSH order.queue order-1001Redis 会把这条消息交给某一个正在等待的消费者。c1 或 c2 中只有一个能拿到 order-1001。另一个消费者不会拿到同一条消息。这叫竞争消费。多个消费者共同竞争队列中的消息提高处理能力。注意BLPOP 一次只取一条消息。 拿到消息后命令结束。 想继续消费需要再次执行 BLPOP。未来在 Java 中会放进循环while (true) { // 阻塞获取消息 // 处理消息 }6. List 不存在时是否自动创建生产者第一次执行RPUSH order.queue order-1001如果order.queue不存在Redis 会自动创建一个 List再写入消息。因此不需要提前创建队列。不同命令的行为操作队列不存在时的行为RPUSH/LPUSH自动创建 List 并写入消息LPOP/RPOP返回(nil)不会创建BLPOP/BRPOP阻塞等待不会创建取走最后一条消息后空 List 通常自动删除例如消费者先执行BLPOP order.queue 0即使order.queue还不存在也会阻塞等待。之后生产者执行RPUSH order.queue order-1001Redis 会自动创建 List并立刻将消息交给等待中的消费者。7. List 的可靠性问题普通 List 队列的消费过程队列中有消息 ↓ 消费者 BLPOP / LPOP ↓ 消息立即从 List 删除 ↓ 消费者开始处理业务如果消费者取到消息后立刻宕机消费者拿到 order-1001 ↓ Redis 已删除 order-1001 ↓ 消费者还没写入 MySQL 就宕机 ↓ 消息丢失因此RPUSH BLPOP 简单但不能可靠保证消息一定被处理完成。它适合日志、简单通知、可容忍少量丢失的异步任务。不适合订单创建、支付、库存扣减、秒杀订单等重要业务。8. List 的改进处理中队列可以准备两个 Listorder.queue 待处理队列 order.processing 正在处理队列生产者发送消息RPUSH order.queue order-1001消费者不直接删除消息而是使用BRPOPLPUSH order.queue order.processing 0含义从 order.queue 右边取出一条消息 放到 order.processing 左边 整个移动过程是原子的。流程待处理队列 ↓ 原子移动 ↓ 处理中队列 ↓ 业务处理成功 ↓ 从处理中队列删除消息处理成功后LREM order.processing 1 order-1001如果消费者宕机消息仍保留在 order.processing 中 不会立即消失。但这种方案的重试、超时检测、重复消费控制、失败记录等逻辑都要自己实现。因此 List 可以改进可靠性但实现复杂度会逐渐接近 Stream。三、Redis Pub/Sub 发布订阅1. Pub/Sub 的基本思想Pub/Sub 是 Publish / Subscribe 的缩写即发布 / 订阅。它不是传统“一个消费者取走一条消息”的队列而是广播机制。发布者 Publisher ↓ PUBLISH 频道 Channel ↓ SUBSCRIBE 多个订阅者 Subscriber例如发布者 ↓ news ├── 订阅者 A 收到 ├── 订阅者 B 收到 └── 订阅者 C 收到一条消息会被所有当前在线、订阅该频道的客户端收到。2. Pub/Sub 核心命令命令作用PUBLISH channel message向频道发布消息SUBSCRIBE channel精确订阅频道UNSUBSCRIBE channel取消精确订阅PSUBSCRIBE pattern按模式订阅频道PUNSUBSCRIBE pattern取消模式订阅3. 基础发布与订阅终端 A 作为订阅者SUBSCRIBE news表示订阅频道news终端 B 作为发布者PUBLISH news hello redis返回(integer) 1表示当前有 1 个订阅者收到了消息。终端 A 会收到1) message 2) news 3) hello redis含义message 表示收到普通频道消息 news 消息所属频道 hello redis 消息内容4. Pub/Sub 的广播特性假设两个订阅者都执行SUBSCRIBE news然后发布者发送PUBLISH news 秒杀活动开始两个订阅者都会收到秒杀活动开始这和 List 不同。List一条消息通常只会被一个消费者取走。Pub/Sub一条消息会广播给所有在线订阅者。5. Pub/Sub 为什么不适合订单消息Pub/Sub 不保存历史消息。假设没有订阅者时发布PUBLISH news 活动开始返回(integer) 0表示当前没有在线订阅者。这条消息不会保存。之后即使有人执行SUBSCRIBE news也收不到之前那条消息。因此 Pub/Sub 的特点是先订阅才能收到之后发布的消息。如果订阅者断线、宕机、网络异常断线期间的消息会直接错过。Pub/Sub 没有消息持久化 确认机制 Pending List 失败重试 消费者组所以它不适合订单 支付 库存扣减 秒杀下单这些业务必须保证消息可靠处理。6. Pub/Sub 适合的场景Pub/Sub 适合“所有在线客户端都应该立刻知道”的通知型场景。例如聊天室消息广播 系统维护通知 缓存失效通知 在线用户状态变化 实时监控大屏更新 WebSocket 推送辅助通知可以把 Pub/Sub 理解为微信群公告。在线的人能立刻看到不在线的人会错过。7. 订阅多个频道可以一次订阅多个频道SUBSCRIBE news system.notice cache.clear之后只要其中任意频道有消息当前客户端都能收到。例如PUBLISH news 新闻更新 PUBLISH system.notice 服务器十分钟后维护 PUBLISH cache.clear 请清理商品缓存8. 取消普通订阅取消某个频道UNSUBSCRIBE news取消当前客户端全部普通订阅UNSUBSCRIBE对应关系SUBSCRIBE 订阅精确频道 UNSUBSCRIBE 取消精确频道订阅9. 模式订阅PSUBSCRIBE除了精确订阅频道还可以按模式订阅。例如PSUBSCRIBE news.*表示订阅所有以news.开头的频道。可以匹配news.sports news.tech news.game news.local发布者执行PUBLISH news.sports 比赛开始或者PUBLISH news.tech Redis 通知模式订阅者都会收到。模式订阅收到的格式类似1) pmessage 2) news.* 3) news.sports 4) 比赛开始含义pmessage 表示模式订阅消息 news.* 当前订阅模式 news.sports 实际发布频道 比赛开始 消息内容10. PUNSUBSCRIBE 的作用PUNSUBSCRIBE是取消模式订阅。例如之前执行PSUBSCRIBE news.*现在取消PUNSUBSCRIBE news.*取消全部模式订阅PUNSUBSCRIBE对应关系订阅方式取消方式SUBSCRIBE newsUNSUBSCRIBE newsPSUBSCRIBE news.*PUNSUBSCRIBE news.*因此PUNSUBSCRIBE 的含义是 Pattern Unsubscribe 即取消模式订阅。11. 普通订阅和模式订阅重叠的问题假设同一个客户端既执行SUBSCRIBE news.sports又执行PSUBSCRIBE news.*之后发布PUBLISH news.sports 比赛开始该客户端可能收到两次消息一次来自精准订阅 news.sports 一次来自模式订阅 news.*因此开发时应避免同一个业务对同一频道建立重叠订阅否则可能重复处理通知。四、List 与 Pub/Sub 对比对比项Redis ListRedis Pub/Sub核心模式任务队列消息广播一条消息由谁处理一个消费者所有在线订阅者消息是否保存暂时保存在 List 中不保存消费者离线时消息可暂存在队列直接错过消息是否支持阻塞等待支持BLPOP/BRPOP订阅后持续接收是否有确认机制没有没有是否容易丢消息消费后宕机可能丢离线或异常时可能丢典型用途简单异步任务实时广播通知是否适合订单不够可靠不适合五、最终记忆List 队列最常见写法RPUSH order.queue 消息 BLPOP order.queue 0含义生产者从右边放消息 消费者从左边阻塞取消息 实现先进先出的竞争消费。优点简单 支持阻塞 多个消费者可竞争消费缺点消息取出后立即删除 消费者宕机可能导致消息丢失 没有确认、重试、消费者组机制Pub/Sub最常见写法SUBSCRIBE news PUBLISH news 消息含义发布者向频道广播消息 所有当前在线订阅者都会收到。模式订阅PSUBSCRIBE news.* PUNSUBSCRIBE news.*优点实时广播 使用简单 适合通知类场景缺点不保存消息 订阅者离线就会丢消息 没有确认和重试 不适合订单等重要业务一句话区分List谁抢到谁处理。 Pub/Sub谁订阅谁都收到。 Stream可靠地分配、确认、恢复消息。
利用Galaxy插件与Python脚本实现BurpSuite中AES_CBC流量自动化加解密 1. 项目概述:为什么我们需要在BurpSuite里搞加解密? 做Web安全测试的朋友,对BurpSuite这个“瑞士军刀”肯定不陌生。抓包、改包、重放、爆破,这些常规操作大家都很熟。但近几年,随着应用安全意识的提升,越来… 2026/7/5 9:22:37
Matlab双级心电滤波实战包:IIR+巴特沃斯联合去噪,含真实ECG数据与5组可视化结果 本文还有配套的精品资源,点击获取 简介:直接运行test2.m就能看到完整ECG信号处理效果,用coursework2ECG.mat里的实测心电信号做输入,先过IIR滤波器压掉工频干扰和基线漂移,再用巴特沃斯带通滤波器聚焦QRS波段&#… 2026/7/5 9:20:36
Wand-Enhancer终极指南:5分钟配置开源增强工具,免费解锁WeMod完整功能 Wand-Enhancer终极指南:5分钟配置开源增强工具,免费解锁WeMod完整功能 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否厌倦… 2026/7/5 10:39:11
MIPI D-PHY/C-PHY信号完整性与EMI工程实践解析 1. 项目概述:MIPI D-PHY/C-PHY信号完整性与EMI的工程实践困境 在移动设备和高清视频传输领域,MIPI D-PHY和C-PHY接口已成为事实上的行业标准。作为一名从事高速接口设计多年的工程师,我经常遇到一个令人困惑的现象:明明示波器上的… 2026/7/5 10:39:11
汽车雨刮器设计:运动轨迹优化与材料工程解析 1. 项目背景与需求分析 汽车前挡风玻璃雨刮器作为车辆安全行驶的关键部件,其设计质量直接影响驾驶视野清晰度。这个看似简单的机械装置,实际上需要综合考虑流体力学、材料科学、机械结构等多学科知识。在雨天行驶时,一个优秀的雨刮器设计应当… 2026/7/5 10:39:11
工业4-20mA电流环技术解析与工程实践 1. 工业4-20mA电流环技术背景解析在工业自动化领域,4-20mA电流环标准已经持续服役超过60年,这种看似简单的模拟信号传输方式至今仍是过程控制系统的首选方案。其核心优势在于电流信号的天然抗干扰特性——与电压信号不同,电流在传输过程中不会… 2026/7/5 10:37:10
双有源桥变换器扩展移相调制优化策略 1. 双有源桥变换器与扩展移相调制概述 双有源桥(Dual Active Bridge, DAB)直流变换器作为一种高效的双向功率转换拓扑,在现代电力电子系统中扮演着重要角色。其核心优势在于能够实现电气隔离的同时,高效地完成双向能量传输。这种特… 2026/7/5 10:37:10
DDR内存系统架构设计与信号完整性分析 1. DDR内存系统架构概述 现代DDR内存系统是一个复杂的多学科工程系统,其设计需要同时考虑电气、机械、热力和材料等多方面因素。作为计算机系统中的核心部件,DDR内存的性能和可靠性直接影响整个系统的表现。本文将深入剖析DDR内存系统的架构设计要点&… 2026/7/5 10:35:10
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/5 0:01:32
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/5 0:01:32
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/5 0:05:36
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/5 0:01:32
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/5 0:01:32
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/5 0:05:36