Redis 发布/订阅(Pub/Sub)消息系统

RedisBeginner
立即练习

介绍

在本实验中,你将探索 Redis 的发布/订阅(Pub/Sub)消息系统。你将学习如何订阅频道、发布消息以及取消订阅。本实验将通过 SUBSCRIBEPUBLISHUNSUBSCRIBEPSUBSCRIBE 命令带你体验这些基础操作。

使用 SUBSCRIBE 订阅频道

在本步骤中,你将学习如何使用 SUBSCRIBE 命令在 Redis 中订阅一个频道。订阅频道可以让接收发送到该频道的消息。这是 Redis 发布/订阅消息系统中的一个基本概念。

终端 1:订阅频道

打开你的第一个终端(我们称之为终端 1)。你可以使用 LabEx 环境中提供的 Xfce 终端。

使用 redis-cli 命令连接到 Redis 服务器:

redis-cli

你应该会看到 Redis 的提示符:127.0.0.1:6379>

使用 SUBSCRIBE 命令订阅一个名为 mychannel 的频道:

SUBSCRIBE mychannel

输出结果类似于:

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "mychannel"
3) (integer) 1

让我们来解析一下输出内容:

  • "subscribe":表示你已经成功订阅了一个频道。
  • "mychannel":你所订阅的频道名称。
  • (integer) 1:你当前订阅的频道总数。

重要提示:请保持终端 1 打开,并且保持 redis-cli 会话处于活动状态并订阅该频道。请不要关闭此终端或按 Ctrl+C,因为这会取消你对该频道的订阅。在下一步中,我们将使用第二个终端来发布消息。

使用 PUBLISH 发布消息

在本步骤中,你将学习如何使用 PUBLISH 命令在 Redis 中向频道发布消息。发布消息是发布/订阅系统的核心功能,允许你向特定频道的所有订阅者发送数据。

终端 2:发布消息

打开第二个终端(我们称之为终端 2)。你可以在 Xfce 终端中打开一个新标签页。

使用 redis-cli 命令连接到 Redis 服务器:

redis-cli

你应该会看到 Redis 的提示符:127.0.0.1:6379>

现在,使用 PUBLISH 命令向 mychannel 频道发布一条消息:

PUBLISH mychannel "Hello, Redis!"

终端 2 的输出将是接收到该消息的客户端数量:

(integer) 1

在这个例子中,输出为 (integer) 1,因为你在上一步中已经在终端 1 中对 mychannel 进行了活动订阅。

在终端 1 中观察消息

现在切换回终端 1(你在步骤 1 中订阅 mychannel 的地方)。你应该会看到你刚刚发布的消息实时显示出来:

1) "message"
2) "mychannel"
3) "Hello, Redis!"

这表明:

  • "message":表示这是一条发布的消息。
  • "mychannel":消息发布到的频道。
  • "Hello, Redis!":实际的消息内容。

测试实时消息传递

你现在可以体验实时消息传递:

  1. 返回终端 2 并发布更多消息。
  2. 切换到终端 1 查看它们即时出现。
  3. 尝试发布不同的消息以观察实时通信。

示例 - 在终端 2 中:

PUBLISH mychannel "This is message 2"
PUBLISH mychannel "Real-time messaging works!"

Important: Keep both Terminal 1 and Terminal 2 with their redis-cli sessions active. We'll continue using both terminals in the next steps.

使用 UNSUBSCRIBE 取消订阅

在本步骤中,你将学习如何使用 UNSUBSCRIBE 命令在 Redis 中取消订阅频道。取消订阅会将客户端从特定频道的订阅者列表中移除,从而阻止其接收随后发布到该频道的消息。

终端 1:退出订阅模式

前往终端 1(你当前正订阅 mychannel 的地方)。你应该会看到显示「Reading messages... (press Ctrl-C to quit)」的订阅状态。

由于终端 1 处于订阅模式,你无法直接执行常规的 Redis 命令。要取消订阅,你需要先退出订阅模式:

  1. 按下 Ctrl+C 退出订阅模式。

  2. 你应该会看到 redis-cli 会话结束并返回到终端提示符。

  3. 重新连接到 Redis:

    redis-cli
    
  4. 现在你可以执行 UNSUBSCRIBE 命令(尽管由于断开连接已经自动取消订阅,这一步不是必须的):

    UNSUBSCRIBE mychannel
    

注意:当你按下 Ctrl+C 时,实际上已经断开了所有订阅。这里展示 UNSUBSCRIBE 命令是为了演示目的,但在实际操作中,断开连接会自动取消你对所有频道的订阅。

终端 1 中的输出将如下所示:

1) "unsubscribe"
2) "mychannel"
3) (integer) 0

让我们解析一下输出:

  • "unsubscribe":表示你已经取消订阅了某个频道。
  • "mychannel":你取消订阅的频道名称。
  • (integer) 0:你当前订阅的频道数量。现在是 0,因为你已经取消订阅了 mychannel

终端 2:测试取消订阅后的发布

现在切换到终端 2,并向 mychannel 发布另一条消息:

PUBLISH mychannel "Is anyone still there?"

终端 2 的输出将是:

(integer) 0

这表明没有客户端收到该消息,因为你在终端 1 中已经取消了对该频道的订阅。

验证未收到消息

观察终端 1 —— 你应该会发现没有任何新消息出现,因为你已经取消了对该频道的订阅。

这证明了取消订阅频道可以防止你接收随后发布到该频道的消息,而发布者仍然可以发送消息(只是没有人会收到)。

重要提示:请保持两个终端及其 redis-cli 会话处于活动状态,以便进行下一步。

使用 PSUBSCRIBE 进行模式订阅

在本步骤中,你将学习如何在 Redis 中使用 PSUBSCRIBE 命令按模式(Pattern)订阅频道。PSUBSCRIBE 允许你订阅匹配指定模式的多个频道。当你想要从一组相关频道接收消息,而又不想逐个订阅时,这非常有用。

终端 1:模式订阅

由于你在上一步中已经取消订阅了 mychannel终端 1 现在应该显示常规的 Redis 提示符。

终端 1 中,使用 PSUBSCRIBE 命令订阅匹配模式 news.* 的频道:

PSUBSCRIBE news.*

输出结果类似于:

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

让我们解析一下输出:

  • "psubscribe":表示你已成功订阅了一个模式。
  • "news.*":你订阅的模式。其中 .* 是一个通配符,可以匹配任意字符。
  • (integer) 1:你当前订阅的模式总数。

终端 2:向匹配模式的频道发布消息

前往终端 2,使用 PUBLISH 命令向 news.sports 频道发布一条消息:

PUBLISH news.sports "Sports news update!"

终端 2 的输出将是接收到该消息的订阅者数量:

(integer) 1

观察模式匹配

切回终端 1(你订阅模式的地方)。你应该会看到你刚刚发布的消息:

1) "pmessage"
2) "news.*"
3) "news.sports"
4) "Sports news update!"

这表明:

  • "pmessage":表示这是一条模式匹配的消息。
  • "news.*":匹配的模式。
  • "news.sports":消息实际发布到的频道。
  • "Sports news update!":消息内容。

测试多个频道

终端 2 中,尝试向匹配该模式的不同频道发布消息:

PUBLISH news.technology "New AI breakthrough!"
PUBLISH news.weather "Sunny skies ahead!"
PUBLISH sports.basketball "This won't match the pattern"

终端 1 中观察到,只有 news.* 频道的消息被接收了,而 sports.basketball 没有被接收,因为它不匹配 news.* 模式。

重要提示:请保持两个终端及其 redis-cli 会话处于活动状态。模式订阅展示了如何同时监听多个相关的频道。

总结

在本实验中,你探索了 Redis 发布/订阅消息系统的基础知识。你学习了如何使用 SUBSCRIBE 命令订阅频道、使用 PUBLISH 命令向频道发布消息、使用 UNSUBSCRIBE 命令取消订阅频道,以及使用 PSUBSCRIBE 命令按模式订阅频道。这些命令对于使用 Redis 构建实时消息应用程序至关重要。