Redis(07)消息订阅与发布Pub/Sub -- 附有示例

Redis-消息订阅与发布(Pub/Sub)

Pub/Sub模式是一种消息传递方式,通过将消息发送到一个频道(channel)中,所有订阅该频道的客户端都可以接收到该消息。主要包括以下四个方面:

  1. 发布和接收消息的命令:包括PUBLISH、SUBSCRIBE、UNSUBSCRIBE等。
  2. 频道管理命令:包括CHANNELS、NUMSUB、NUMPAT等,用于查看和管理已经创建的频道。
  3. 订阅事件的命令:包括PSUBSCRIBE、PUNSUBSCRIBE等,用于订阅匹配多个频道的消息。

使用场景

消息订阅与发布的使用场景很多,下面列举一些常见的场景:

  1. 实时聊天:多个用户通过WebSocket连接到一个实时聊天服务器,通过消息订阅与发布功能实现用户之间的实时聊天。

  2. 实时计费:在希望实时计费的场景中,应用可以发布已处理一笔事务或发生某些事件的消息。一个或多个订阅者可以接收这些通知,然后执行必要的操作。

  3. 数据缓存更新:在数据缓存中,经常使用消息订阅与发布机制来更新缓存。当一个数据块被更新时,相关的代码发布一个消息,让订阅者动态地检测到消息并更新对应的缓存。

  4. 实时数据流处理:对于轮询量大的实时数据流处理任务,传统的轮询以及消息轮询的方式会对CPU和网络资源造成大的压力,使用消息订阅与发布能够有效减轻CPU和网络负载。

  5. 任务队列:消息订阅与发布功能可以用于构建任务队列,发布者发布一个任务,而订阅者之一或多个负责执行该任务。

总之,消息订阅与发布是一种非常灵活的通信机制,在几乎所有需要一对多通信的应用程序中都有广泛的应用。

发布和接收消息

发布消息的命令是PUBLISH。它用于将一条消息发送到指定的频道中。如果频道不存在,则会自动创建一个新的频道。

接收消息的命令是SUBSCRIBE和PSUBSCRIBE。SUBSCRIBE命令用于订阅一个具体的频道,而PSUBSCRIBE命令则用于订阅匹配一个模式的频道(使用通配符)。

当一个客户端订阅了一个频道之后,它就可以接收到该频道中发布的所有消息。如果一个客户端订阅了多个频道,那么它就会同时接收到这些频道中的消息。

在客户端接收到消息时,它会触发一个回调函数,该函数可以处理接收到的消息。在处理完消息后,客户端可以发送一个确认消息给服务器,表示该消息已经被成功接收。这个确认消息可以让服务器立刻删除已经被接收的消息,从而避免消息被重复接收。

以下是一个示例,演示如何使用Redis Pub/Sub模式发布和接收消息

Publish和Subscribe

在Redis中,发布和订阅消息是通过Pub/Sub模式来实现的。Pub/Sub模式包含两个基本概念:发布(Publish)和订阅(Subscribe)。

在Pub/Sub模式中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber)。发布者将消息发送到特定的频道(Channel),订阅者可以订阅一个或多个频道,以接收这些频道里的所有消息。

下面是一个使用Redis Pub/Sub模式的示例:

  1. 创建一个新的频道

PUBLISH

我们可以使用PUBLISH命令来创建一个新的频道并发送一条消息。例如,我们可以使用以下命令在频道test-channel中发布一条消息:

PUBLISH test-channel "Hello, Redis!"

这条命令将消息"Hello, Redis!"发送到频道test-channel中。

  1. 订阅频道

SUBSCRIBE

我们可以使用SUBSCRIBE命令来订阅一个频道。例如,我们可以使用以下命令来订阅test-channel频道:

SUBSCRIBE test-channel

这条命令告诉Redis客户端开始订阅test-channel频道,并且一旦有新的消息发布到该频道中,客户端就会自动接收该消息。

  1. 发布消息

我们可以使用PUBLISH命令来向某个频道中发布一条消息。例如,我们可以使用以下命令来向test-channel频道中发布一条新消息:

PUBLISH test-channel "My first Redis message!"

这条命令将消息’My first Redis message!'发送到test-channel频道中。

  1. 接收消息

当使用SUBSCRIBE命令订阅一个频道时,Redis客户端就会自动等待并接收来自该频道的消息。例如,在我们订阅了test-channel频道后,Redis客户端将开始等待该频道中的新消息。

当test-channel频道中有新的消息时,Redis客户端就会收到一个消息对象。该消息对象包含三个部分:消息类型、频道和消息内容。

频道管理

Redis Pub/Sub模式中有一些频道管理命令,可用于管理频道的订阅和发布。以下是一些常用的频道管理命令及其作用:

  1. SUBSCRIBE:向Redis服务器订阅一个或多个频道。语法:SUBSCRIBE channel [channel ...]
  2. UNSUBSCRIBE:取消客户端对一个或多个频道的订阅。语法:UNSUBSCRIBE [channel [channel ...]]
  3. PSUBSCRIBE:向Redis服务器订阅一个或多个符合指定模式的频道。语法:PSUBSCRIBE pattern [pattern ...]
  4. PUNSUBSCRIBE:取消客户端对一个或多个符合指定模式的频道的订阅。语法:PUNSUBSCRIBE [pattern [pattern ...]]
  5. PUBSUB CHANNELS:列出当前已知的通道。语法:PUBSUB CHANNELS [pattern]
  6. PUBSUB NUMSUB:获取给定频道的订阅者数量。语法:PUBSUB NUMSUB channel [channel ...]
  7. PUBSUB NUMPAT:获取已订阅模式的数量。语法:PUBSUB NUMPAT

这些命令可以帮助我们管理我们的订阅和发布行为。SUBSCRIBE和UNSUBSCRIBE用于订阅和取消订阅特定的频道,PSUBSCRIBE和PUNSUBSCRIBE用于订阅和取消订阅符合指定模式的频道。

PUBSUB CHANNELS和PUBSUB NUMSUB可以帮助我们了解当前已经订阅了哪些频道,以及这些频道有多少订阅者。PUBSUB NUMPAT可以告诉我们有多少模式被订阅了。

这些频道管理命令使得Redis Pub/Sub模式变得更加灵活和强大,可以更好地管理我们的订阅和发布过程。

SUBSCRIBE

  1. SUBSCRIBE: 订阅一个或多个频道。

命令格式: SUBSCRIBE channel [channel ...]

例如: SUBSCRIBE news tech sports

说明:向 Redis 服务器订阅名为 news、tech 和 sports 的频道。

UNSUBSCRIBE

  1. UNSUBSCRIBE: 取消订阅一个或多个频道。

命令格式: UNSUBSCRIBE [channel [channel ...]]

例如: UNSUBSCRIBE news tech

说明:取消 Redis 服务器上 news 和 tech 频道的订阅。

PSUBSCRIBE

  1. PSUBSCRIBE: 订阅一个或多个通过匹配模式得到的频道。

命令格式: PSUBSCRIBE pattern [pattern ...]

例如: PSUBSCRIBE news.* tech.*

说明:订阅以 news 和 tech 起始的所有频道,如 news.sports、tech.business 等。

PUNSUBSCRIBE

  1. PUNSUBSCRIBE: 取消订阅一个或多个通过匹配模式得到的频道。

命令格式: PUNSUBSCRIBE [pattern [pattern ...]]

例如: PUNSUBSCRIBE news.* tech.*

说明:取消已订阅的所有以 news 和 tech 开头的频道。

PUBSUB CHANNELS

  1. PUBSUB CHANNELS: 列出当前已知的频道。

命令格式: PUBSUB CHANNELS [pattern]

例如: PUBSUB CHANNELS

说明:返回 Redis 订阅系统中所有已知频道的列表。

例子:PUBSUB CHANNELS n*

说明:返回 Redis 订阅系统中以 n 开头的所有已知频道的列表。

PUBSUB NUMSUB

  1. PUBSUB NUMSUB: 获取频道的订阅者数量。

命令格式: PUBSUB NUMSUB channel [channel ...]

例如: PUBSUB NUMSUB news tech

说明:返回以 news 和 tech 为名字的频道的订阅者数量。

PUBSUB NUMPAT

  1. PUBSUB NUMPAT: 获取已订阅模式的数量。

命令格式: PUBSUB NUMPAT

说明:返回已经使用 PSUBSCRIBE 命令订阅的模式数量。

命令示例:

SUBSCRIBE 示例

假设我们有一个名为 “Market” 的 Redis 频道,用于接收来自不同用户的订单信息。

现在,有两个用户 A 和 B 都希望订阅该频道以便接收市场订单消息。

A 用户可以使用 SUBSCRIBE 命令将自己订阅到 “Market” 频道上:

SUBSCRIBE Market

该用户现在已经成功地订阅了 “Market” 频道,并可以开始接收市场订单数据。

PSUBSCRIBE 示例

B 用户通过 PSUBSCRIBE 命令使用通配符 * 为 “Market” 订阅了所有子频道:

PSUBSCRIBE Market.*

该用户已经成功地订阅了所有以 “Market.” 为前缀的 Redis 频道,这意味着不仅可以接收 “Market” 频道上的数据,还可以接收 “Market.A”、“Market.B” 等子频道上的数据。

当新订单消息被发布到 “Market” 频道时,这两个已订阅该频道的用户都将收到相应的数据。

UNSUBSCRIBE 示例

当用户 A 不再需要从 “Market” 频道接收消息时,可以使用 UNSUBSCRIBE 命令取消其订阅:

UNSUBSCRIBE Market

PUNSUBSCRIBE 示例

用户 B 可以使用 PUNSUBSCRIBE 取消其订阅:

PUNSUBSCRIBE Market.*

这样一来,当有新的订单消息被发布时,只有用户 A 可以接收到它们。

这是一个简单的 Redis Pub/Sub 示例,说明了如何使用 Pub/Sub 命令来订阅和取消订阅 Redis 频道,以及如何使用通配符来订阅多个频道。

下面我将详细地介绍 Redis Pub/Sub 命令中 PUBSUB CHANNELS、PUBSUB NUMSUB 和 PUBSUB NUMPAT 的作用和用法。

PUBSUB CHANNELS 示例

  • PUBSUB CHANNELS 命令

PUBSUB CHANNELS 命令用于获取 Redis 中所有已知的频道名称,在使用该命令时,不需要传递任何参数。

例如,假设我们有三个频道 “news”, “tech” 和 “sports”,那么我们可以使用以下命令列出所有已知的频道名称:

PUBSUB CHANNELS

执行成功后,该命令将返回一个列表,其中包含了 “news”, “tech” 和 “sports” 三个频道的名称。

PUBSUB NUMSUB 示例

  • PUBSUB NUMSUB 命令

PUBSUB NUMSUB 命令用于获取一个或多个频道的订阅者数量。在使用该命令时,需要传递一个或多个频道名称作为命令参数。

例如,假设用户 A 和 B 分别订阅了 “news” 和 “tech” 两个频道,那么我们可以使用以下命令查询这两个频道的订阅者数量:

PUBSUB NUMSUB news tech

执行成功后,该命令将返回一个列表,其中包含了两个键值对,分别是 “news” 和 “tech” 频道的名称和对应的订阅者数量。

需要注意的是,如果某个频道没有订阅者,那么该频道的名称在返回值中不会出现。

PUBSUB NUMPAT 示例

  • PUBSUB NUMPAT 命令

返回当前使用模式匹配订阅模式的客户端的数量。

返回值

一个整数,表示当前使用模式匹配订阅的客户端数量。

例子

redis> PSUBSCRIBE news.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.*"
3) (integer) 1

redis> PUBSUB NUMPAT
(integer) 1

redis> UNSUBSCRIBE news.*
3) "unsubscribe"
4) "news.*"
5) (integer) 0

redis> PUBSUB NUMPAT
(integer) 0

在上面的示例中,我们通过 PSUBSCRIBE 命令订阅了 “news.*” 模式,使用 PUBSUB NUMPAT 命令查询订阅该模式的客户端数量,得到的结果是 1。接下来,我们通过 UNSUBSCRIBE 命令取消了对该模式的订阅,再次使用 PUBSUB NUMPAT 命令查询订阅该模式的客户端数量,得到的结果是 0。

总之,PUBSUB NUMPAT 命令用于获取已经使用 PSUBSCRIBE 命令订阅的模式数量。该命令的返回值是一个整数,表示当前已经使用 PSUBSCRIBE 命令订阅的模式数量。

命令

这些都是Redis的Pub/Sub(发布/订阅)相关命令。主要用于在多个客户端间实现消息的发布与订阅。

PUB/SUB命令主要分为两类:

发布消息命令:

PUBLISH channel message: 将消息message发布到频道channel。
SPUBLISH channel message: 将消息message发布到频道channel,只推送给频道的订阅者的一个随机抽样。

订阅频道命令:

SUBSCRIBE channel [channel …]: 订阅给定的一个或多个频道的消息。
PSUBSCRIBE pattern [pattern …]: 订阅符合给定模式的频道。
SSUBSCRIBE channel [channel …]: 订阅给定的一个或多个频道的消息,只接收频道的订阅者的一个随机抽样。

其他PUB/SUB相关命令:

PUNSUBSCRIBE [pattern …]: 退订所有给定模式的频道。
UNSUBSCRIBE [channel …]: 退订给定的频道。
SUNSUBSCRIBE [channel …]:退订给定的频道,只退订频道的订阅者的一个随机抽样。
PUBSUB CHANNELS [pattern]: 查看订阅与发布系统中的频道。
PUBSUB NUMPAT: 获取订阅模式的数量。
PUBSUB NUMSUB channel: 获取给定频道的订阅者数量。
PUBSUB SHARDCHANNELS: 查看群集中的所有频道订阅信息。
PUBSUB SHARDNUMSUB channel: 在群集中获取给定频道的订阅者数量。

Pub/Sub功能允许发送者将消息发送到频道,并让感兴趣的接收者订阅这些频道,以获取它们所发送的消息。 这种模式是一种强大而简单的通信模式。

全部命令

以下是对于这些Redis Pub/Sub相关命令的解释:

  1. PSUBSCRIBE:订阅一个或多个符合给定模式的频道,接收符合给定模式的频道发布的消息。
  2. PUBLISH:将消息发布到指定的频道。
  3. PUBSUB CHANNELS:列出所有被订阅的频道。
  4. PUBSUB NUMPAT:返回该Redis服务器已订阅的模式数量。
  5. PUBSUB NUMSUB:当给定至少一个频道名时,返回订阅了这些频道的客户端和它们订阅的频道的数量。
  6. PUBSUB SHARDCHANNELS:列出所有被使用的共享实例的订阅的频道。
  7. PUBSUB SHARDNUMSUB:返回给定共享实例的所有客户端订阅的频道数量。
  8. PUNSUBSCRIBE:退订一个或多个符合给定模式的频道。
  9. SPUBLISH:将消息发布到指定的频道,且消息只会被推送给当前处于活跃状态的订阅者。
  10. SSUBSCRIBE:订阅一个或多个给定的集合中的元素,即在新元素加入集合时,返回对应的集合名称。
  11. SUBSCRIBE:订阅一个或多个给定的频道,接收这些频道发布的消息。
  12. SUNSUBSCRIBE:退订一个或多个给定的集合中的元素。
  13. UNSUBSCRIBE:退订一个或多个给定的频道。

这些命令提供了灵活的Pub/Sub功能,让开发者可以在Redis中构建出高效而有用的实现。其中,SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE和PUNSUBSCRIBE是最常用的Pub/Sub命令,它们支持订阅/退订单个或多个频道或模式。而其他命令则支持更细粒度的操作,如列出当前订阅的频道,查询已订阅的模式数量等等。

更详细的命令说明可以参考Redis官方文档:https://redis.io/commands/#pubsub

下面是一个简单的Spring Boot Redis Pub/Sub示例代码: 首先需要在pom.xml中添加redis和spring-boot-starter-data-redis依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.6.0</version> </dependency> ``` 然后编写一个Redis消息监听器: ```java @Component public class RedisMessageListener { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private MessageListenerAdapter messageListenerAdapter; @PostConstruct public void init() { new Thread(() -> { Jedis jedis = new Jedis("localhost"); jedis.subscribe(messageListenerAdapter, "test-channel"); }).start(); } @Bean public MessageListenerAdapter messageListenerAdapter() { return new MessageListenerAdapter(new RedisMessageSubscriber()); } public class RedisMessageSubscriber { public void handleMessage(String message) { System.out.println("Received message: " + message); } } } ``` 然后可以在其他地方发布消息Redis中: ```java @RestController public class RedisController { @Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("/publish") public String publish() { stringRedisTemplate.convertAndSend("test-channel", "Hello, Redis!"); return "Message sent"; } } ``` 这样,当调用/publish接口时,就会向Redis的test-channel频道发布一条消息RedisMessageListener中的RedisMessageSubscriber就会收到该消息并进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bilal-abdurehim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值