簡介
Redis 發布訂閱 (pub/sub) 是一種消息通信模式:發送者 (pub) 發送消息,訂閱者 (sub) 接收消息。
Redis 客戶端可以訂閱任意數量的頻道
發布訂閱命令
訂閱
redis 127.0.0.1:6379> SUBSCRIBE runoobChat Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "redisChat" 3) (integer) 1
發布
redis 127.0.0.1:6379> PUBLISH runoobChat "Redis PUBLISH test" (integer) 1 redis 127.0.0.1:6379> PUBLISH runoobChat "Learn redis by runoob.com" (integer) 1 # 訂閱者的客戶端會顯示如下消息 1) "message" 2) "runoobChat" 3) "Redis PUBLISH test" 1) "message" 2) "runoobChat" 3) "Learn redis by runoob.com"
-
開啟本地 Redis 服務,開啟兩個 redis-cli 客戶端。
-
在第一個 redis-cli 客戶端輸入 SUBSCRIBE runoobChat,意思是訂閱
runoobChat
頻道。 -
在第二個 redis-cli 客戶端輸入 PUBLISH runoobChat "Redis PUBLISH test" 往 runoobChat 頻道發送消息,這個時候在第一個 redis-cli 客戶端就會看到由第二個 redis-cli 客戶端發送的測試消息
發布訂閱代碼
# -*- coding: utf-8 -*- import redis class RedisPubSub(): """ Redis 發布訂閱類 :return: """ def __init__(self, channel): self.__conn = redis.Redis(host=APP_SESSION.get("host"), port=APP_SESSION.get("port"), password=APP_SESSION.get("password"), db=APP_SESSION.get('db')) self.chan_pub = channel self.chan_sub = channel def publish(self, msg): """ 發布 :param msg: :return: """ self.__conn.publish(self.chan_pub, msg) return True def subscribe(self): """ 訂閱 :return: """ pub = self.__conn.pubsub() pub.subscribe(self.chan_sub) pub.parse_response() return pub if __name__ == '__main__': pass
發布訂閱的缺陷
概要說一下就是,PUBLISH和SUBSCRIBE的缺陷在於客戶端必須一直在線才能接收到消息,斷線可能會導致客戶端丟失消息,
除此之外,舊版的redis可能會由於訂閱者消費不夠快而變的不穩定導致崩潰,甚至被管理員殺掉
第一個原因是和redis系統的穩定性有關。對於舊版的redis來說,如果一個客戶端訂閱了某個或者某些頻道,但是它讀取消息的速度不夠快,那么不斷的積壓的消息就會使得redis輸出緩沖區的體積越來越大,這可能會導致redis的速度變慢,甚至直接崩潰。也可能會導致redis被操作系統強制殺死,甚至導致操作系統本身不可用。新版的redis不會出現這種問題,因為它會自動斷開不符合client-output-buffer-limit pubsub配置選項要求的訂閱客戶端
第二個原因是和數據傳輸的可靠性有關。任何網絡系統在執行操作時都可能會遇到斷網的情況。而斷線產生的連接錯誤通常會使得網絡連接兩端中的一端進行重新連接。如果客戶端在執行訂閱操作的過程中斷線,那么客戶端將會丟失在斷線期間的消息,這在很多業務場景下是不可忍受的