简介
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配置选项要求的订阅客户端
第二个原因是和数据传输的可靠性有关。任何网络系统在执行操作时都可能会遇到断网的情况。而断线产生的连接错误通常会使得网络连接两端中的一端进行重新连接。如果客户端在执行订阅操作的过程中断线,那么客户端将会丢失在断线期间的消息,这在很多业务场景下是不可忍受的