huangxuegang

你要悄悄学php,然后惊艳所有人
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

redis的发布和订阅

Posted on 2020-07-30 16:33  一花多叶无菩提  阅读(418)  评论(0)    收藏  举报

什么是redis的发布和订阅(pub/sub)

订阅,取消订阅和发布实现了发布/订阅消息范式,发布者不是计划发送消息给特定的订阅者,而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅。订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不需要知道什么样的发布者发布的。这种发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑。

redis可以实现发布订阅和消息队列的功能,两者的区别在于

1)redis的订阅者可以是多个,且可以同时处理发布上来的消息,如果订阅者不在线(服务没有启动)消息将丢失,消息没有持久化。发布和订阅是一块执行的,缺少一个直接忽略这个消息
2)消息队列只能有一个客户端来处理,处理完之后消息就被标记或删除,即使服务端没有启动消息也不会丢失
3)两者的使用场景要根据业务数据的准确度,敏感性决定,比如日志就可以用redis发布订阅来实现,丢失一点也没有关系

php消费者代码

<?php 
/**
 *channel频道:生产者和消费者直接操作对象
 *publish 生产者:向channel发送消息
 *subscribe消费者:匹配订阅一个或者多个channel
 *psubscribe消费者:匹配或订阅一个或多个channel
 *punsubscribe退订:匹配退订,无参数则退订全部channel
 *unsubscribe退订 :退订指定的channel,无参数则退订全部的channel
 *pubsub列出当前活动的channel(至少有一个订阅)
 *
 * 注意事项:1.生产者publish消息的时候会打开一个链接,publish后连接可以立即关闭
 *              2.channel只接收publish发送的消息,自身不存储消息,如果channel没订阅,就被丢弃
 *              3.订阅的消费者需要一直在线,连接断开意味着退订              
 */
//设置php脚本执行时间
// set_time_limit(0);
//设置socket连接超时时间
// ini_set('default_socket_timeout', -1);
/**
 * 声明测试频道名称
 * @var string
 */
try {
  $redis = new Redis();
  $redis->connect('192.168.75.133', 6379);
  for ($i=0;$i<5;$i++) {
    $data = array('key' => 'key'.$i, 'data' => 'testdata');
    $ret = $redis->publish($channelName, json_encode($data));
    print_r($ret);
  }
} catch (Exception $e) {
  echo $e->getMessage();
} 

php生产者代码

<?php
$channelName="testPubSub";
$channelName2="testPubSub2";

try {
    $redis=new Redis();

    $redis->connect('192.168.75.132',6379);
    for($i=0;$i<5;$i++){
        $data=['key'=>$i,"data"=>"testdata"];

         $ret=$redis->publish($channelName,json_encode($data));
         print_r($ret);
    }
} catch (Exception $e) {
    // 35590012
    echo 123;
    
}