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

Redis 发布订阅模式完全指南

引言

在前面的 Redis 文章中,我们学习了五种基本数据类型、持久化、主从复制和哨兵模式。今天要讲的是 Redis 的发布订阅功能——一种轻量级的消息通信模式。

发布订阅的核心思想很简单:有人发布消息到频道,订阅了该频道的人就能收到消息。这和微信公众号非常像——你关注了一个公众号(订阅频道),号主发文章(发布消息),你就能收到推送。

虽然专业消息队列(如 RabbitMQ、Kafka)功能更强大,但 Redis 的发布订阅足够轻量、零配置,适合中小型项目中的实时通知、聊天消息等场景。

第一部分:基础命令

一、订阅频道

# 语法:SUBSCRIBE 频道名 [频道名 ...] # 订阅一个或多个频道 # 终端1:订阅 news 和 sports 频道 127.0.0.1:6379> SUBSCRIBE news sports Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "news" 3) (integer) 1 1) "subscribe" 2) "sports" 3) (integer) 2

执行 SUBSCRIBE 后,客户端进入订阅模式,会一直阻塞等待消息,直到手动Ctrl+C退出。

二、发布消息

# 语法:PUBLISH 频道名 消息内容 # 终端2:向 news 频道发布消息 127.0.0.1:6379> PUBLISH news "今天科技圈发生了大事" (integer) 2 # 返回值 2 表示有 2 个订阅者收到了消息 # 向 sports 频道发布消息 127.0.0.1:6379> PUBLISH sports "CBA总决赛今晚打响" (integer) 2

终端1 收到的消息

为甚会出现这种\xe4此类信息呢,那他是错误的还是怎么回事???

原因:

其实收到\xe4\xbb...这样的数据,是因为Redis 客户端和服务器之间的编码/解码不一致

简单说:Redis 存进去的是"好的"中文,但你用来显示的程序把它当成了"原始字节码"直接打印了。(所以他们其实是一个东西,只是展示的样子不同罢了,就像不同语言一样汉语与英语)

那么如何解决呢?

在进入 Redis 之前,先设置一下编码,或者在连接时指定:

# 方法1:设置终端编码 export LANG=zh_CN.UTF-8 redis-cli # 方法2:连接时加上 --raw 参数(推荐) redis-cli --raw

加上--raw后,再XREADGET,应该就能直接显示中文了。

三、退订频道

# 语法:UNSUBSCRIBE [频道名 ...] # 不带参数则退订所有频道 127.0.0.1:6379> UNSUBSCRIBE news # 只退订 news 127.0.0.1:6379> UNSUBSCRIBE # 退订所有

第二部分:模式订阅

除了订阅具体频道,Redis 还支持模式匹配——订阅所有名称匹配某种模式的频道。

# 语法:PSUBSCRIBE 模式 [模式 ...] # 订阅所有以 "news." 开头的频道 127.0.0.1:6379> PSUBSCRIBE news.*

通配符规则

模式匹配不匹配
news.*news.sportsnews.technewssports.news
news.*.chinanews.tech.chinanews.sports.chinanews.china
*所有频道
# 测试 # 终端1:模式订阅 127.0.0.1:6379> PSUBSCRIBE news.* # 终端2:发布消息 127.0.0.1:6379> PUBLISH news.tech "AI 新突破" (integer) 1 # 终端1 收到: 1) "pmessage" # 模式消息类型 2) "news.*" # 匹配的模式 3) "news.tech" # 实际频道名 4) "AI 新突破" # 消息内容

普通订阅 vs 模式订阅

订阅方式命令收到消息格式用途
普通订阅SUBSCRIBEmessage订阅具体频道
模式订阅PSUBSCRIBEpmessage按模式匹配批量订阅

退订模式

# 语法:PUNSUBSCRIBE [模式 ...] 127.0.0.1:6379> PUNSUBSCRIBE news.*

第三部分:查看频道状态

# 查看当前活跃的频道(至少有一个订阅者) 127.0.0.1:6379> PUBSUB CHANNELS 1) "news" 2) "sports" # 查看匹配模式的活跃频道 127.0.0.1:6379> PUBSUB CHANNELS news.* 1) "news.tech" 2) "news.sports" # 查看某个频道的订阅者数量 127.0.0.1:6379> PUBSUB NUMSUB news sports 1) "news" 2) (integer) 3 # news 有 3 个订阅者 3) "sports" 4) (integer) 2 # sports 有 2 个订阅者 # 查看模式订阅的数量 127.0.0.1:6379> PUBSUB NUMPAT (integer) 2 # 当前有 2 个模式订阅

第四部分:实际应用场景

一、实时聊天系统

# 用户A 发送消息 PUBLISH room_101 "大家好,我是新来的" # 用户B、C、D(都订阅了 room_101)立即收到

二、系统通知推送

# 场景:电商系统,订单状态变更通知 # 用户下单后,订阅自己的订单频道 SUBSCRIBE order:10086 # 后台处理订单,状态变更时发布消息 PUBLISH order:10086 "您的订单已发货,快递单号:SF1234567890" # 用户收到实时通知

三、配置热更新

第五部分:C 语言实现发布订阅

一、发布者

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <hiredis/hiredis.h> int main() { // 连接 Redis redisContext *c = redisConnect("127.0.0.1", 6379); if (c == NULL || c->err) { printf("连接失败: %s\n", c->errstr); return -1; } // 发布消息 redisReply *reply = redisCommand(c, "PUBLISH news %s", "Hello, Redis 发布订阅!"); if (reply == NULL) { printf("发布失败\n"); return -1; } printf("订阅者数量: %lld\n", reply->integer); freeReplyObject(reply); redisFree(c); return 0; }

编译

gcc publisher.c -o publisher -lhiredis

二、订阅者

#include <stdio.h> #include <stdlib.h> #include <hiredis/hiredis.h> int main() { redisContext *c = redisConnect("127.0.0.1", 6379); if (c == NULL || c->err) { printf("连接失败: %s\n", c->errstr); return -1; } // 订阅频道 redisReply *reply = redisCommand(c, "SUBSCRIBE news"); if (reply == NULL) { printf("订阅失败\n"); return -1; } freeReplyObject(reply); // 循环接收消息 printf("等待消息...\n"); while (redisGetReply(c, (void**)&reply) == REDIS_OK) { if (reply->type == REDIS_REPLY_ARRAY && reply->elements == 4) { // 收到消息:[message, 频道名, 消息内容, 空] printf("频道: %s\n", reply->element[1]->str); printf("内容: %s\n", reply->element[2]->str); } freeReplyObject(reply); } redisFree(c); return 0; }

第六部分:发布订阅的局限性

缺点说明解决方案
消息不持久化订阅者不在线时发的消息会丢失改用 Redis Stream 或专业消息队列
无确认机制发布者不知道消息是否被处理改用 RabbitMQ(ACK 机制)
无消息堆积消息不会被存储,即发即忘改用 Kafka(持久化消息)
订阅者阻塞SUBSCRIBE 后客户端只能接收消息需要专门的连接处理

什么时候用 Redis 发布订阅?

场景是否适合
实时聊天✅ 适合
系统通知✅ 适合
配置热更新✅ 适合
订单处理(不能丢消息)❌ 不适合
金融交易(需要确认)❌ 不适合

总结

一、核心命令速查

命令作用
SUBSCRIBE channel订阅频道
UNSUBSCRIBE [channel]退订频道
PUBLISH channel msg发布消息
PSUBSCRIBE pattern模式订阅
PUNSUBSCRIBE [pattern]退订模式
PUBSUB CHANNELS查看活跃频道
PUBSUB NUMSUB查看订阅者数量

二、消息格式

订阅方式消息格式
普通订阅[message, 频道名, 消息内容]
模式订阅[pmessage, 模式, 频道名, 消息内容]

三、一句话记忆

Redis 发布订阅是一种轻量级消息通信模式,发布者通过 PUBLISH 向频道发消息,订阅者通过 SUBSCRIBE 实时接收。支持通配符模式匹配(PSUBSCRIBE),但不持久化、不确认,适合实时通知等场景,不适合关键业务消息。

http://www.gsyq.cn/news/1417833.html

相关文章:

  • 深度评测:LaserGRBL开源激光雕刻控制软件的技术架构与性能分析
  • 小白也能轻松上手:用AI建站工具从注册到发布的极速实操指南
  • OpenBoard:为什么这款开源Android输入法是你的隐私保护终极选择?
  • 5分钟掌握《重返未来:1999》智能小助手M9A:彻底解放你的游戏时间
  • 上位机知识篇---/script和/bin文件
  • 2026年5月专业的铑水回收公司怎么选择厂家推荐榜,高浓度铑水、低浓度铑水、含杂铑水、废铑催化剂溶液厂家选择指南 - 海棠依旧大
  • 关系运算符,逻辑运算符,三元运算符
  • 模块二,Agent的推理模式是什么
  • Windows鼠标指针美化终极指南:免费获取macOS风格指针包
  • 开发者发布深度指南:将Claude Code从对话工具变为可运营智能体工作环境
  • 2026 年 5 月临床三基备考 电子版题库与模拟题使用参考 - 讲清楚了
  • 实时流式批处理架构升级迫在眉睫:DeepSeek RAG场景下微批(micro-batch)与滑动窗口协同优化方案(限24小时开放下载)
  • Sora 2商用级短片量产方案,深度拆解头部MCN已封存的2.3秒镜头调度公式
  • 2026 年 5 月证券从业突围:培训 APP 与刷题资料实测避坑指南 - 讲清楚了
  • 终极免费方案:3步在浏览器中制作专业EPUB电子书
  • 养老公司待五年,不如AI岗干一年?AI大模型应用开发
  • 【Claude消息中间件设计黄金法则】:基于37个真实故障复盘提炼的12条不可妥协原则(含AWS/Azure/GCP跨云适配清单)
  • 2026年Q2专业电源一体化数据采集防雷箱安装公司深度解析 - 2026年企业资讯
  • 企业级AI翻译选型生死线:Gemini vs. DeepL vs. NLLB-200——实测金融/医疗/法律场景F1-score对比(附可复现测试集)
  • 跟着 MDN 学CSS day_25:(高级区块效果)
  • 2026 中山工厂搬家公司口碑榜 本地优选正规搬厂名单 - 从来都是英雄出少年
  • Vivado IP核实战:复数浮点累加器的精度与延迟权衡(以2022.1版本为例)
  • 仅限首批500名Go开发者:Gemini推理服务Go代码生成器内测权限(含自动类型推导与错误上下文注入功能)
  • 长文本问题的本质,不是“装得下“,而是“看得见、记得住、说得准“
  • 油藏多相多组分相平衡实验及计算方法解析【附数据】
  • STM32F407驱动WS2812,除了延时函数,这3种更高效的方法你试过吗?
  • 给ADC设计抗混叠滤波器,别只算截止频率!从SAR型ADC输入电路实战说起
  • 为什么越来越多的智能语音设备,开始采用“独立语音DSP模组”架构?
  • 不用写一行音频算法!1 天给机器人加上 360° 闻声转头功能
  • 实测Taotoken平台API调用的响应延迟与稳定性体验报告