当前位置: 首页 > news >正文

redis订阅/发布 分享

一、引入(是什么?)

  Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

  各位都是务实的人,所以我就不长篇大论讲他的概念了,举个类似的例子来说明就好。

  大家肯定都有用微信,我们平时关注了订阅号,每次他发布消息的时候,我们就能看到。这就是一个消息订阅/发布的场景。

  在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。

 

二、redis订阅/发布功能使用场景(为什么用?)

  这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊,实时提醒等功能。

  我在项目中用到的场景:神奇电波落地页接口需要提供购买人和购买人数

三、实例:订阅/发布命令(怎么用?)

     

1.SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。

2.PUBLISH channel message 将信息发送到指定的频道。

3.PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态

 例:PUBSUB CHANNELS test*

4.PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。

 

5.UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。

6.PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。

官方教程:http://www.redis.net.cn/tutorial/3514.html

 

 

四、php实现redis订阅发布

SUBSCRIBE端代码:

<?php
/**
 * redis sub(消息订阅端)
 */

$redis = new Redis();
$res = $redis->pconnect('121.41.88.209', 6379);
$redis->setOption(\Redis::OPT_READ_TIMEOUT,-1);
$redis->subscribe(array('test'), 'callback');

// 回调函数,这里写处理逻辑
function callback($instance, $channelName, $message) 
{ echo $channelName, "==>", $message,PHP_EOL; }

PUBLISH端代码:

<?php
/**
 * redis sub(消息发布端)
 */
$redis = new Redis();
// 第一个参数为redis服务器的ip,第二个为端口
$res = $redis->connect('121.41.88.209', 6379);
// test为发布的频道名称,hello,world为发布的消息
$res = $redis->publish('test','hello,world'.rand(00000,99999));

SUBSCRIBE端代码(redis集群):

$RedisNode = array('192.168.0.224:7000', '192.168.0.224:7001', '192.168.0.224:7002', '192.168.0.224:7003', '192.168.0.224:7004', '192.168.0.224:7005', 1.5, 1.5);
$redis = getRedis();
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
$redis->subscribe(array('testChannel'), 'callback');

// 回调函数,这里写处理逻辑
function callback($instance, $channelName, $message)
{
 echo $channelName, "==>", $message,PHP_EOL;
}


function getRedis($redisConfig=array())
{
    global $RedisNode, $RedisPassWord;
    try {
        if(!empty($redisConfig)){
            $redis = new Redis();
            $redis->connect($redisConfig['host'],$redisConfig['port']);
            $redis->auth($redisConfig['pwd']);
            return $redis;
        }
        $redis = new RedisClusterClass(null,$RedisNode);
        return $redis;
    } catch (Exception $e) {
        exit;
    }
}

 

五、注意事项

1.在命令执行redis订阅端脚本时,发现在终端会输出:

PHP Fatal error:  Uncaught exception 'RedisException' with message 'read error on connection' in …

       这个错误大概的意思就是遇到了一个未捕获的异常:RedisException,返回的错误信息是读取连接错误。 应该是redis的客户端读取超时原因导致。 

       (最新测试,在我的服务器上发现,只要1分钟没有接收到消息就会报错)

错误解决办法:

通过Redis自带的常量设置

$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
 
 

2.连接redis集群时,1分钟退出

错误解决办法:

设置,default_socket_time = -1 :

ini_set('default_socket_timeout', '-1');

 3.消费要快!

    Redis有输出缓冲区限制,发布的消息要及时消费,否则sub客户端会被强制关闭,查看redis的日志可以看到这句报错:

subscribe scheduled to be closed ASAP for overcoming of output buffer limits.

 六、与其他消息系统对比

1.Redis发布订阅与Kafka
(1)redis 消息推送(基于分布式 pub/sub)多用于实时性较高的消息推送,Kafka有一些延迟

(2)Redis无法对消息持久化存储,一旦消息被发送,如果没有订阅者接收,那么消息就会丢失。Kafka中消息被消费后不会被删除,而是到配置的expire时间后,才删除

(3)kafka中多个订阅者可以分组,发布一个消息后,同一个组里只有一个订阅者会收到该消息,这样可以用作负载均衡。例:有100台服务器每台服务器都是一个订阅者,都订阅了这个 topic,但是他们可能分为三组,A组50台,用来真的做发布文章,B组20台,用来写log,C组30台,用来存档备份……

            

 

 

2.Redis发布订阅与ActiveMQ的比较

(1)ActiveMQ支持多种消息协议,包括AMQP,MQTT,Stomp等,并且支持JMS规范,但Redis没有提供对这些协议的支持;
(2)ActiveMQ提供持久化功能,但Redis无法对消息持久化存储,一旦消息被发送,如果没有订阅者接收,那么消息就会丢失;
(3)ActiveMQ提供了消息传输保障,当客户端连接超时或事务回滚等情况发生时,消息会被重新发送给客户端,Redis没有提供消息传输保障。
总之,ActiveMQ所提供的功能远比Redis发布订阅要复杂,毕竟Redis不是专门做发布订阅的,
但是如果系统中已经有了Redis,并且需要基本的发布订阅功能,就没有必要再安装ActiveMQ了,因为可能ActiveMQ提供的功能大部分都用不到,而Redis的发布订阅机制就能满足需求。

 

 

    

转载于:https://www.cnblogs.com/liaokaichang/articles/6937513.html

相关文章:

  • 红与黑
  • 读取Web.Config中的设置参数之二
  • 自学有感7
  • Http之Get/Post请求区别
  • 清河好程序猿训练营是什么?
  • 分享:Ajax工具文件
  • 洛谷P1287 盒子与球 数学
  • 识别地图上的地名-- 笔记一
  • 如何破解来自私有云的安全挑战
  • SQL优化34条[转载]
  • 你的每行代码值多少钱?
  • 日常开发工作快照(一)
  • Catalog Service - 解析微软微服务架构eShopOnContainers(三)
  • 2008-08-23
  • MIEngine —— Visual Studio 调试引擎
  • 时间复杂度分析经典问题——最大子序列和
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 30秒的PHP代码片段(1)数组 - Array
  • IOS评论框不贴底(ios12新bug)
  • JAVA_NIO系列——Channel和Buffer详解
  • Mithril.js 入门介绍
  • MySQL-事务管理(基础)
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • SegmentFault 2015 Top Rank
  • Webpack 4 学习01(基础配置)
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 新手搭建网站的主要流程
  • nb
  • zabbix3.2监控linux磁盘IO
  • #android不同版本废弃api,新api。
  • #pragam once 和 #ifndef 预编译头
  • $$$$GB2312-80区位编码表$$$$
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (bean配置类的注解开发)学习Spring的第十三天
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (图)IntelliTrace Tools 跟踪云端程序
  • (学习日记)2024.01.09
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .NET Core中Emit的使用
  • .net 中viewstate的原理和使用
  • .NetCore部署微服务(二)
  • .考试倒计时43天!来提分啦!
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @RequestBody的使用
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [ SNOI 2013 ] Quare
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [].shift.call( arguments ) 和 [].slice.call( arguments )