深入Redis学习教程之消息发布与订阅( Publish/Subscribe)教程

作者 : IT 大叔 本文共1505个字,预计阅读时间需要4分钟 发布时间: 2020-10-20

发布订阅

角色: 发布者  订阅者  频道

发布订阅的通信模型:

深入Redis学习教程之消息发布与订阅( Publish/Subscribe)教程插图

发布订阅模型

发布者和订阅者都在客户端,而频道在redis服务端
发布者发布消息到redis服务器,频道会将消息广播到关注了这个频道的所有订阅者。

命令
publish channel message     # 发布消息,返回订阅者个数
subscribe channel   # 订阅,可以接多个channel
unsubscribe channel     # 取消订阅,可以接多个channel

对比消息队列和发布订阅:
二者的共同点是:消息发布者和订阅者都在客户端,频道或者队列在服务端。
不同点:发布订阅会将消息发给所有订阅者,但是消息队列则只有一个订阅者能接收到(或者说是抢到)队列弹出来的元素。

深入Redis学习教程之消息发布与订阅( Publish/Subscribe)教程插图(2)

消息队列模型

所以消息队列除了能用来缓解请求压力之外,还能够实现一个"抢"的功能,例如实现抢红包功能。不过消息队列用来处理并发请求用的是阻塞的brpop命令,而实现抢红包应该是列表中已经有红包,直接使用rpop就好。

注意,订阅者只可以接收到订阅之后的消息,订阅之前频道发的消息是接收不到的。

Python演示:
订阅者 subscriber.py

# coding=utf-8

import redis
import time

r = redis.Redis("127.0.0.1",6379)
p = r.pubsub()  # 创建一个PubSub 发布订阅对象

p.subscribe("test_channel")   # 订阅一个频道

while True:
    # 接收消息
    data = p.get_message()
    if data:
        print(data)
    time.sleep(0.1)

# 或者使用p.listen(),listen()会返回一个生成器,可以遍历这个生成器来获取消息,当频道没有消息的时候,listen会阻塞循环;当有消息时,会接收消息
#for message in p.listen():
#    print(message)

发布者 publisher.py

# coding=utf-8

import redis

r = redis.Redis("127.0.0.1",6379)
res = r.publish("test_channel","This is test data");

print(res)

订阅者先订阅
python subscriber.py

发布者再发布
python publisher.py

注意:当客户端订阅了一个频道,这个客户端脚本就会一直处于一个阻塞的运行状态。如果想要结束脚本就要调用 unsubscribe 取消订阅

# coding=utf-8

import redis
import time

r = redis.Redis("127.0.0.1",7000)
p = r.pubsub()  # 创建一个PubSub 发布订阅对象

p.subscribe("test_channel")   # 订阅一个频道

count = 0
for message in p.listen():
    count+=1
    print(message)
    if count>5:
        p.unsubscribe("test_channel")

如果是用php来订阅消息,取消订阅后脚本还无法结束运行,此时要die强行终止才行:

<?php 
    set_time_limit(0);
    $r = new Redis();
    $r->connect("127.0.0.1",7000);
    $r->subscribe(['test'],"cb");
    function cb($redis,$channel,$msg){
        var_dump($msg);
        $redis->unsubscribe(["test"]);
        die;
    }
?>
免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » 深入Redis学习教程之消息发布与订阅( Publish/Subscribe)教程

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论