一文搞懂Redis的发布订阅

来自文章集合:一文带你搞懂redis使用过程(持续更新中)

Redis发布订阅

什么是发布/订阅

当你去订阅一份电子报,当有新的新闻发生时,报社会将新闻推送给你。使用redis可以像订阅一份电子报一样订阅redis频道,然后当有新消息发布到该频道时,你就会收到通知。

发布者就像是报社,它发送消息到特定频道,而订阅者就像是订阅者,他们可以从频道中接受信息。

当redis频道无人订阅时,频道会自动删除。

如何订阅频道和接受频道消息

redis可以使用SUBSCRIBE命令来订阅一个或多个频道,然后使用PUBLISH命令向频道发布消息

下面我新建一个redis客户端1,先订阅3个频道

json 复制代码
127.0.0.1:6379> SUBSCRIBE rediChat1 redisChat2 redisChat3
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "rediChat1"
3) (integer) 1
1) "subscribe"
2) "redisChat2"
3) (integer) 2
1) "subscribe"
2) "redisChat3"
3) (integer) 3

新建一个redis客户端2,订阅redisChat3频道

json 复制代码
127.0.0.1:6379> SUBSCRIBE redisChat3
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat3"
3) (integer) 1

新建一个redis客户端3,进行消息推送

json 复制代码
127.0.0.1:6379> publish redisChat3 "Hello World"
(integer) 2
127.0.0.1:6379> publish redisChat2 "I Want to go home"
(integer) 1

监听客户端的显示

json 复制代码
//	redis客户端1
27.0.0.1:6379> SUBSCRIBE rediChat1 redisChat2 redisChat3
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "rediChat1"
3) (integer) 1
1) "subscribe"
2) "redisChat2"
3) (integer) 2
1) "subscribe"
2) "redisChat3"
3) (integer) 3
1) "message"
2) "redisChat3"
3) "Hello World"
1) "message"
2) "redisChat2"
3) "I Want to go home"


//	redis客户端2
127.0.0.1:6379> SUBSCRIBE redisChat3
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat3"
3) (integer) 1
1) "message"
2) "redisChat3"
3) "Hello World"

命令介绍

查看当前已创建的频道

PUBSUB channels

订阅给定的一个或多个频道,频道不存在则创建频道

SUBCRIBE <channel> [channel]

例子如下:

json 复制代码
127.0.0.1:6379> pubsub channels
(empty list or set)
127.0.0.1:6379> SUBSCRIBE redis_chat1 redis_chat2 redis_chat3 redis_chat4
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redis_chat1"
3) (integer) 1
1) "subscribe"
2) "redis_chat2"
3) (integer) 2
1) "subscribe"
2) "redis_chat3"
3) (integer) 3
1) "subscribe"
2) "redis_chat4"
3) (integer) 4
1) "message"
2) "redis_chat1"
3) "hello world"

订阅一个或多个符合给定模式的频道

PSUBSCRIBE <pattern> [pattern]

例子如下:

json 复制代码
127.0.0.1:6379> PSUBSCRIBE redis_chat*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redis_chat*"
3) (integer) 1
1) "pmessage"
2) "redis_chat*"
3) "redis_chat1"
4) "hello world"

发送消息到指定的频道

PUBLISH <channel> <message>

json 复制代码
127.0.0.1:6379> PUBLISH redis_chat1 "hello world"
(integer) 2

返回的参数是2,是指消息成功发送到两个订阅者消息中。上面两个订阅者频道,会收到如上述例子中的消息。


频道退订

在windows打开的cmd中,订阅频道之后回阻塞,只能通过<ctrl + c>来取消频道的订阅,但是在代码的使用中,不会一直阻塞在,需要通过命令来取消频道的订阅,命令如下:

退订所有给定模式的频道:

PUNSUBSCRIBE <pattern> [pattern...]

退订指定的频道:

UNSUBSCRIBE <channel> [channel...]

下面例子是使用java的jedis操作,这里大概知道就好,有兴趣可以了解:java中redis的使用

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class UnsubscribeExample {
    public static void main(String[] args) {
		//	创建一个jedis,用于操作redis
        Jedis jedis = new Jedis("localhost");
		//	创建一个订阅者,用来处理事件:消息、订阅、取消订阅
        JedisPubSub jedisPubSub = new JedisPubSub() {
            @Override
            public void onMessage(String channel, String message) {
                System.out.println("Received message: " + message + " from channel: " + channel);
            }

            @Override
            public void onSubscribe(String channel, int subscribedChannels) {
                System.out.println("Subscribed to channel: " + channel);
            }

            @Override
            public void onUnsubscribe(String channel, int subscribedChannels) {
                System.out.println("Unsubscribed from channel: " + channel);
            }
        };
		//	订阅`channel1`频道
        jedis.subscribe(jedisPubSub, "channel1");
		      
        // 业务操作

        // 退订`channel1`频道
        jedisPubSub.unsubscribe("channel1");
    }
}

使用场景和需要注意的问题

使用场景

Redis 发布/订阅模式常常被用于实现消息的广播和实时通知。以下是一些使用场景:

  • 实时通讯:在聊天应用中,可以使用发布/订阅模式向所有在线用户广播消息。
  • 数据更新通知:在分布式系统中,当数据更新时,可以使用发布/订阅模式通知其他节点更新其缓存。
  • 实时消息传递:用于实时更新例如股票市场行情、实时新闻等。
  • 订阅服务:允许用户订阅特定主题或内容类型的服务。
  • 多播消息:在需要将同一消息发送给多个消费者时,可以使用发布/订阅模式。

这些使用场景都可以利用 Redis 的发布/订阅功能来实现实时的消息传递和广播。

需要注意的问题

  • 消息丢失: Redis 的发布/订阅模式不会保证消息的持久性,如果有订阅者处于离线状态,它将无法接收到在其离线期间发布的消息。可以通过实现消息确认机制、持久化存储或使用消息队列等方法来避免消息丢失。
  • 消息订阅和取消: 订阅者需要明确知道何时订阅消息以及何时取消订阅,否则可能会导致消息堆积或无法接收到最新的消息。
  • 消息传递保证: Redis 的发布/订阅模式不保证每个订阅者都能接收到消息,因为这取决于网络的状况以及订阅者自身的处理速度。
  • 订阅者的处理能力: 如果订阅者的处理能力不足以处理高频率的消息传递,可能会导致消息堆积和处理延迟。处理延迟可能会导致其处于离线状态,无法在接收消息。使用时 需要评估订阅者的处理能力和负载情况,确保其能够处理和消化所接收到的消息,避免消息堆积导致的性能问题或故障。
  • 消息格式和解析: 发布者和订阅者之间需要对消息的格式达成共识,以便正确解析和处理消息内容。

在使用 Redis 的发布/订阅功能时,需要考虑这些问题,并设计相应的应对方案以确保消息的可靠传递和处理。

引申

频道名可以与已有字段的键(key)名相同?

是的,频道名可以与已有的键(key)名相同。在 Redis 中,频道名和键名是不同的命名空间,它们之间没有冲突。

相关推荐
欧恩意5 小时前
【Tools】Java反汇编工具推荐
java·汇编
苍何5 小时前
字节发力,豆包大模型2.0 震撼来袭(附 Trae 实测)
后端
苍何6 小时前
不会剪辑的人,开始用 AI 批量出爆款了
后端
苍何6 小时前
百度 APP 正式接入 OpenClaw,所有人限时免费!
后端
寻星探路6 小时前
【JVM 终极通关指南】万字长文从底层到实战全维度深度拆解 Java 虚拟机
java·开发语言·jvm·人工智能·python·算法·ai
lbb 小魔仙6 小时前
【Java】Java 实战项目:手把手教你写一个电商订单系统
android·java·python
星河耀银海6 小时前
Java安全开发实战:从代码防护到架构安全
java·安全·架构
青云交6 小时前
Java 大视界 -- 基于 Java 的大数据可视化在城市水资源管理与节水策略制定中的应用
java·java 大数据·java 大数据可视化·城市水资源管理·spark 数据清洗·echarts 热力图·管网漏损控制
紫陌涵光6 小时前
112. 路径总和
java·前端·算法
workflower6 小时前
多变量时间序列预测
java·hadoop·nosql·需求分析·big data·结对编程