php使用redis的有序集合zset实现延迟队列应用示例

 更新时间:2020年02月20日 11:22:26   作者:怀素真  
这篇文章主要介绍了php使用redis的有序集合zset实现延迟队列,结合具体实例形式分析了PHP基于redis的有序集合zset实现延迟队列的具体原理、应用场景及相关操作技巧,需要的朋友可以参考下

本文实例讲述了php使用redis的有序集合zset实现延迟队列。分享给大家供大家参考,具体如下:

延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息。

延迟队列的应用场景:

1、新用户注册,10分钟后发送邮件或站内信。

2、用户下单后,30分钟未支付,订单自动作废。

我们通过redis的有序集合zset来实现简单的延迟队列,将消息数据序列化,作为zset的value,把消息处理时间作为score,每次通过zRangeByScore获取一条消息进行处理。

<?php
class DelayQueue
{
  protected $prefix = 'delay_queue:';
  protected $redis = null;
  protected $key = '';
  public function __construct($queue, $config = [])
  {
    $this->key = $this->prefix . $queue;
    $this->redis = new Redis();
    $this->redis->connect($config['host'], $config['port'], $config['timeout']);
    $this->redis->auth($config['auth']);
  }
  public function delTask($value)
  {
    return $this->redis->zRem($this->key, $value);
  }
  public function getTask()
  {
    //获取任务,以0和当前时间为区间,返回一条记录
    return $this->redis->zRangeByScore($this->key, 0, time(), ['limit' => [0, 1]]);
  }
  public function addTask($name, $time, $data)
  {
    //添加任务,以时间作为score,对任务队列按时间从小到大排序
    return $this->redis->zAdd(
      $this->key,
      $time,
      json_encode([
        'task_name' => $name,
        'task_time' => $time,
        'task_params' => $data,
      ], JSON_UNESCAPED_UNICODE)
    );
  }
  public function run()
  {
    //每次只取一条任务
    $task = $this->getTask();
    if (empty($task)) {
      return false;
    }
    $task = $task[0];
    //有并发的可能,这里通过zrem返回值判断谁抢到该任务
    if ($this->delTask($task)) {
      $task = json_decode($task, true);
      //处理任务
      echo '任务:' . $task['task_name'] . ' 运行时间:' . date('Y-m-d H:i:s') . PHP_EOL;
      return true;
    }
    return false;
  }
}
$dq = new DelayQueue('close_order', [
  'host' => '127.0.0.1',
  'port' => 6379,
  'auth' => '',
  'timeout' => 60,
]);
$dq->addTask('close_order_111', time() + 30, ['order_id' => '111']);
$dq->addTask('close_order_222', time() + 60, ['order_id' => '222']);
$dq->addTask('close_order_333', time() + 90, ['order_id' => '333']);

然后,我们写一个php脚本,用来处理队列中的任务。

<?php
set_time_limit(0);
$dq = new DelayQueue('close_order', [
  'host' => '127.0.0.1',
  'port' => 6379,
  'auth' => '',
  'timeout' => 60,
]);
while (true) {
  $dq->run();
  usleep(100000);
}

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php+redis数据库程序设计技巧总结》、《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家PHP程序设计有所帮助。

相关文章

  • PHP程序员学习使用Swoole的理由

    PHP程序员学习使用Swoole的理由

    这篇文章给大家详细分析了为什么PHP程序员需要学习使用Swoole,并通过实例做了分析,有兴趣的朋友参考下。
    2018-06-06
  • PHP提高编程效率的20个要点

    PHP提高编程效率的20个要点

    这篇文章主要介绍了PHP提高编程效率的20个要点的相关资料,需要的朋友可以参考下
    2015-09-09
  • php遍历对象的方法

    php遍历对象的方法

    这篇文章主要介绍了php遍历对象的方法,帮助大家更好的理解和学习使用php,感兴趣的朋友可以了解下
    2021-04-04
  • php把文件设置为插件的技巧方法

    php把文件设置为插件的技巧方法

    在本篇文章里小编给大家分享的是关于php把文件设置为插件的技巧方法,有需要的朋友们可以参考学习下。
    2020-02-02
  • PHP下编码转换函数mb_convert_encoding与iconv的使用说明

    PHP下编码转换函数mb_convert_encoding与iconv的使用说明

    mb_convert_encoding这个函数是用来转换编码的。原来一直对程序编码这一概念不理解,不过现在好像有点开窍了。
    2009-12-12
  • 使用PHP函数scandir排除特定目录

    使用PHP函数scandir排除特定目录

    scandir()函数返回一个数组,其中包含指定路径中的文件和目录。这篇文章主要介绍了使用PHP函数scandir排除特定目录,需要的朋友可以参考下
    2014-06-06
  • preg_match_all使用心得分享

    preg_match_all使用心得分享

    preg_match_all 进行全局正则表达式匹配,这篇文章主要介绍下preg_match_all的相关资料,需要的朋友可以参考下
    2014-01-01
  • php 过滤危险html代码

    php 过滤危险html代码

    用PHP过滤html里可能被利用来引入外部危险内容的代码。有些时候,需要让用户提交html内容,以便丰富用户发布的信息,当然,有些可能造成显示页面布局混乱的代码也在过滤范围内。
    2009-06-06
  • PHP session_start()问题解疑(详细介绍)

    PHP session_start()问题解疑(详细介绍)

    对于PHP的session功能,始终找不到合适的答案,尤其是一些错误,还有一些没有错误的结果,最可怕的就是后者,一直为许多的初学者为难。就连有些老手,有时都被搞得莫名其妙
    2013-07-07
  • php字符串过滤strip_tags()函数用法实例分析

    php字符串过滤strip_tags()函数用法实例分析

    这篇文章主要介绍了php字符串过滤strip_tags()函数用法,结合实例形式分析了php字符串过滤函数strip_tags()功能、参数及相关使用技巧,需要的朋友可以参考下
    2019-06-06

最新评论