为什么用订阅发布机制?原因在于它的速度要比pop、push快很多。

先介绍一下redis的pub/sub功能:

Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系

python zmq 发布订阅 python redis 发布订阅_python

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

python zmq 发布订阅 python redis 发布订阅_python_02

实例一

通俗来讲,就是说我sub端(订阅者)一直监听着,一旦pub端(发布者)发布了消息,那么我就接收过来,举个例子,先是发布者:

#coding:utf-8

import time
import redis
 
number_list = ['300033', '300032', '300031', '300030']
signal = ['1', '-1', '1', '-1']
 
rc = redis.StrictRedis(host='***', port='6379', db=3, password='********')
for i in range(len(number_list)):
    value_new = str(number_list[i]) + ' ' + str(signal[i])
    rc.publish("liao", value_new)  #发布消息到liao

接着我们来看看订阅者:

#coding:utf-8

import time
import redis
 
rc = redis.StrictRedis(host="192.168.101.3", port="6379", db=0, password="chishiba")
ps = rc.pubsub()
ps.subscribe("chishiba")    # 订阅消息
a = 0
for item in ps.listen():        # 监听状态:有消息发布了就拿过来
    #print(type(item))
    a += 1
    if a % 1000 == 0:
        print(a)

实例二(连接池)

redis订阅/发布机制工具类:

import redis
 
 
class RedisHelper:
    def __init__(self):
        self.connection_pool = redis.ConnectionPool(host="127.0.0.1", port=6379)
        self.__conn = redis.Redis(connection_pool=self.connection_pool)#连接redis
 
    def publish(self, pub, msg):
        self.__conn.publish(pub, msg)#根据提供的频道进行消息发布
        return True
 
    def subscribe(self, sub):
        pub = self.__conn.pubsub() # 打开收音机
        pub.subscribe(sub) # 调频道
        pub.parse_response() # 准备接收
        return pub

订阅端:

from redis_utils import RedisHelper
 
red = RedisHelper()#得到实例化对象
while 1:
    data  = red.subscribe("Bao").parse_response()#此时会处于一直订阅的状态有数据就会接收过来
    if data:
        print(str(data[2], encoding="utf-8"))

发布端:

from redis_utils import RedisHelper
 
red = RedisHelper()
while 1:
    data = str(input("请输入您想推送的数据:"))
    if data:
        red.publish("Bao", data)
        print("finished")

总结,要点有两个:

  • 一是连接方式。使用python连接redis有三种方式:①使用库中的Redis类(或StrictRedis类,其实差不多);②使用ConnectionPool连接池(可保持长连接);③使用Sentinel类(如果有多个redis做集群时,程序会自己选择一个合适的连接)。
  • 二是订阅方法。这里使用的是StrictRedis类中的pubsub方法。连接好之后,可使用subscribe或psubscribe方法来订阅redis消息。其中subscribe是订阅一个频道,psubscribe可订阅多个频道(这样写的时候,作为参数的频道应该是一个列表)。之后就可以开始监听了。