基础理解:
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