基礎理解:
redis的發布訂閱機制實際上是一種生產者和消費者模式
發布者向消息通道A發布消息
訂閱A頻道的訂閱者監聽通道A並接收消息
訂閱者通過關閉監聽通道取消訂閱
一旦消息被發送,如果沒有訂閱者接收,消息就會消失
應用場景:
最明顯的就是用於即時聊天,群聊,消息推送等
實現原理:
每個redis服務進程都維護一個表示服務器狀態的結構,結構的pubsub_channel屬性是一個字典,字典的鍵是通道名稱,字典的值是一個鏈表,鏈表保存了所有訂閱此頻道的客戶端
客戶端調用訂閱命令時,就會將客戶端和頻道關聯,並將關聯頻道的消息推送頻道鍵所對應的所有客戶端
使用示例:
發布者:
import redis import time import random import config rds_conn = redis.StrictRedis(host=config.REDIS_HOST, port=config.REDIS_PORT, db=config.REDIS_DB, password=config.REDIS_PASS) """ 發布者ip為本機localhost 訂閱者ip為發布者的外部ip """ def publish(chan_pub, msg): rds_conn.publish(chan_pub, msg) if __name__ == '__main__': while True: rand_num = random.randint(0,1000) publish('testchannel', 'hello world: %s' % rand_num) time.sleep(2)
訂閱者:
import redis import time import config rds_conn = redis.StrictRedis(host=config.REDIS_HOST, port=config.REDIS_PORT, db=config.REDIS_DB, password=config.REDIS_PASS) """ 訂閱者ip為發布者的外部ip """ def subscribe(chan_sub): sub_obj = rds_conn.pubsub() sub_obj.subscribe(chan_sub) cnt = 0 for itm in sub_obj.listen(): print itm # itm為接收的訂閱消息結構體:{u'pattern': None, u'type': 'message', u'channel': 'testchannel', u'data': 'hello world: 418'} # 實際消息為 data # if cnt == 10: # sub_obj.close() # 此處執行,則取消訂閱 # cnt += 1 time.sleep(1) if __name__ == '__main__': subscribe('testchannel')
多機部署:
通常,簡單的消息通信少不了加密,加密通道stunnel就是一種傳輸安全方式,下面是基於加密通道的redis發布訂閱多機部署配置
1. 發布者
1)本機redis配置為本機配置,
2)加密通道為server,接受所有連接請求,開放外部redis端口,連接本機redis
2. 訂閱者
1)本機redis配置為本機配置,
2)加密通道為client=yes, 僅接受本地連接請求,開放外部redis端口,連接發布者redis