Redis Pub/Sub 簡介:PUBLISH、SUBSCRIBE、PSUBSCRIBE
Redis Pub/Sub 是一種強大的消息傳遞范例,可在應用程序的不同部分之間實現實時通信。它是構建可擴展和響應式系統的基石,允許組件在沒有直接依賴的情況下進行交互。本章將全面介紹 Redis Pub/Sub,重點介紹核心命令:PUBLISH、``SUBSCRIBE
?和?PSUBSCRIBE
。我們將探討這些命令的工作原理、它們的用例以及如何有效地實現它們。
了解 Pub/Sub 范例
Pub/Sub 是 Publish/Subscription 的縮寫,是一種消息傳遞模式,其中消息的發送者(發布者)不對消息進行編程,以直接發送給特定的接收者(訂閱者)。相反,發布者將消息分類到通道中,訂閱者表示對一個或多個通道感興趣。當發布者向通道發送消息時,該通道的所有訂戶都會收到該消息。
關鍵概念
- Publisher:?將消息發送到特定通道的實體。
- Subscriber:?從一個或多個通道接收消息的實體。
- Channel:?一個命名的虛擬 “主題” 或 “源” ,用于發布消息。訂閱者收聽這些頻道。
- Message: 從發布服務器傳輸到訂閱服務器的數據。
Redis Pub/Sub 的工作原理
Redis Pub/Sub 直接在 Redis 服務器中實現。客戶端連接到 Redis 服務器,并將消息發布到頻道或訂閱頻道以接收消息。Redis 服務器充當消息代理,將消息從發布者路由到訂閱者。
- 異步通信: Pub/Sub 本質上是異步的。發布者不會等待訂閱者接收消息,訂閱者會在消息發布時接收消息。
- 解耦: Pub/Sub 將發布者和訂閱者分離。發布者不需要了解訂閱者的任何信息,訂閱者也不需要了解發布者的任何信息。這使得構建可擴展且可維護的系統變得更加容易。
- 一對多通信:?發布到頻道的單條消息可以被多個訂閱者接收。
PUBLISH
?命令
PUBLISH
?命令用于向特定通道發送消息。
語法
PUBLISH channel message
channel
:消息將發布到的通道的名稱。message
:需要發送的消息內容。
例
PUBLISH mychannel "Hello, subscribers!"
此命令將消息 “Hello, subscribers!” 發布到名為 “mychannel” 的頻道。該命令返回一個整數,表示收到消息的訂閱者數量。
實際演示
-
打開兩個?
redis-cli
?終端。 -
在第一個終端中,訂閱頻道 “mychannel”:
SUBSCRIBE mychannel
終端現在將進入偵聽狀態,等待 “mychannel” 上的消息。
-
在第二個終端中,向 “mychannel” 發布一條消息:
PUBLISH mychannel "This is a test message"
第一個終端將收到以下消息:
1. "message" 2. "mychannel" 3. "This is a test message"
第二個終端中的?
PUBLISH
?命令將返回?1
,表示一個訂閱者收到了該消息。
重要注意事項
- 消息傳遞: Redis Pub/Sub 提供至少一次交付。保證將消息傳送到在發布消息時連接的所有訂閱者。但是,如果訂閱者斷開連接并重新連接,則可能會錯過在斷開連接時發布的消息。Redis Pub/Sub? 不會持久保存消息。
- 消息格式:?消息可以是任何字符串。Redis 不強制執行任何特定格式。但是,對于復雜數據,通常使用 JSON 等結構化格式。
SUBSCRIBE
?命令
SUBSCRIBE
?命令用于訂閱一個或多個通道。當客戶端訂閱頻道時,它將接收發布到該頻道的所有消息。
語法
SUBSCRIBE channel [channel ...]
channel
:要訂閱的頻道的名稱。您可以通過在?SUBSCRIBE
?命令后列出多個頻道來訂閱這些頻道。
例
SUBSCRIBE news updates
此命令為客戶端訂閱兩個頻道:“news”和“updates”。
實際演示
-
打開?
3 個 redis-cli
?終端。 -
在第一個終端中,訂閱 “news” 頻道:
SUBSCRIBE news
-
在第二個終端中,訂閱 “news” 和 “updates” 頻道:
SUBSCRIBE news updates
-
在第三個終端中,向 “news” 頻道發布一條消息:
PUBLISH news "Breaking news!"
第一個和第二個終端將接收該消息。
-
在第三個終端中,向 “updates” 頻道發布一條消息:
PUBLISH updates "Software update available"
只有第二個終端會收到此消息。
取消訂閱
要取消訂閱頻道,請使用?UNSUBSCRIBE
?命令:
UNSUBSCRIBE channel [channel ...]
如果未指定頻道,則客戶端將取消訂閱當前訂閱的所有頻道。
重要注意事項
- 阻塞作:
SUBSCRIBE
?命令是一個阻塞作。一旦客戶端訂閱了一個或多個頻道,它將進入偵聽狀態,并且在取消訂閱之前無法執行其他 Redis 命令。 - 專用連接:?通常的做法是將專用的 Redis 連接用于 Pub/Sub 作。這可以防止阻止應用程序中需要執行常規 Redis 命令的其他部分。
PSUBSCRIBE
?命令
PSUBSCRIBE
?命令用于訂閱使用模式的通道。這允許您訂閱與特定模式匹配的多個頻道。
語法
PSUBSCRIBE pattern [pattern ...]
pattern
:一種 glob 樣式模式,指定要訂閱的頻道。
例
PSUBSCRIBE order.*
此命令為客戶端訂閱所有以 “order.” 開頭的頻道,例如 “order.created”、“order.updated” 和 “order.deleted”。
實際演示
-
打開兩個?
redis-cli
?終端。 -
在第一個終端中,訂閱 “order.*” 模式:
PSUBSCRIBE order.*
-
在第二個終端中,將消息發布到不同的 “order” 頻道:
PUBLISH order.created "New order created" PUBLISH order.updated "Order updated" PUBLISH order.deleted "Order deleted"
第一個終端將接收所有 3 條消息。
-
在第二個終端中,將消息發布到與模式不匹配的通道:
PUBLISH product.created "New product created"
第一個終端_將不會_收到此消息。
取消訂閱模式
要取消訂閱模式,請使用?PUNSUBSCRIBE
?命令:
PUNSUBSCRIBE pattern [pattern ...]
如果未指定模式,則 Client 端將取消訂閱當前訂閱的所有模式。
檢查 Pub/Sub 狀態
打開第三個?redis-cli
?終端。
檢查員(3 號航站樓):
PUBSUB CHANNELS
此命令將列出活動通道。如果終端 1 中的訂閱者訂閱了?news:*
?和?chat:room1
,并且沒有其他客戶端正在使用 Pub/Sub,則輸出可能是:
1) "news:sports"
2) "news:politics"
3) "chat:room1"
請注意,列出的通道是消息已發布到的通道,以及有活動訂閱者的通道。
PUBSUB NUMPAT
此命令將返回活動模式訂閱的數量。在這種情況下,它將返回?1
,因為終端 1 中的訂閱者訂閱了?news:*
?模式。
PUBSUB NUMSUB chat:room1 news:sports
此命令將返回?chat:room1
?和?news:sports
?頻道的訂閱者數量。輸出可能是:
1) "chat:room1"
2) "1"
3) "news:sports"
4) "1"
這表示每個頻道都有一個訂閱者。
重要注意事項
- 模式匹配: Redis 對?
PSUBSCRIBE
?使用 glob 樣式模式。以下字符具有特殊含義:*
:匹配零個或多個字符。?
:只匹配一個字符。[]
:匹配括號內的字符之一。
- 多種模式:?您可以使用單個?
PSUBSCRIBE
?命令訂閱多個模式。 - 操作順序: ?如果客戶端同時訂閱了直接通道(使用?
SUBSCRIBE
)和匹配同一通道的模式(使用?PSUBSCRIBE),
?它將收到兩次消息:一次用于直接訂閱,一次用于模式 subscription。
實踐練習
- 簡單的聊天應用程序:?構建一個簡單的聊天應用程序,用戶可以在其中向特定頻道發送消息,訂閱該頻道的所有用戶都將收到這些消息。使用?
PUBLISH
?和?SUBSCRIBE
?命令。 - 實時更新:?模擬股票行情的實時更新。將股票價格發布到不同的渠道(例如,“stock.AAPL“, ”股票。GOOG“),并讓客戶端訂閱他們感興趣的頻道。使用?
PUBLISH
?和?PSUBSCRIBE
?命令。 - 事件通知系統:?設計一個事件通知系統,其中應用程序的不同部分可以將事件發布到特定通道(例如,“user.created”、“order.placed”),并且應用程序的其他部分可以訂閱這些通道以接收通知。使用?
PUBLISH、``SUBSCRIBE
?和?PSUBSCRIBE
?命令。