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


Posted in PHP onFebruary 20, 2020

本文实例讲述了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 相关文章推荐
php实现jQuery扩展函数
Oct 30 PHP
PHP更新购物车数量(表单部分/PHP处理部分)
May 03 PHP
解析PHP中intval()等int转换时的意外异常情况
Jun 21 PHP
解析php中用PHPMailer来发送邮件的示例(126.com的例子)
Jun 24 PHP
PHP实现支持SSL连接的SMTP邮件发送类
Mar 05 PHP
php实现阳历阴历互转的方法
Oct 28 PHP
详解PHP实现异步调用的4种方法
Mar 14 PHP
基于jQueryUI和Corethink实现百度的搜索提示功能
Nov 09 PHP
php mysql实现mysql_select_db选择数据库
Dec 30 PHP
PHP实现可添加水印与生成缩略图的图片处理工具类
Jan 16 PHP
PHP使用XMLWriter读写xml文件操作详解
Jul 31 PHP
PHP删除字符串中非字母数字字符方法总结
Jan 20 PHP
解决windows上php xdebug 无法调试的问题
Feb 19 #PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
Feb 18 #PHP
laravel框架select2多选插件初始化默认选中项操作示例
Feb 18 #PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
Feb 18 #PHP
PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC
Feb 16 #PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
Feb 15 #PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
Feb 15 #PHP
You might like
咖啡历史、消费和行业趋势
2021/03/03 咖啡文化
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
PHP中的命名空间相关概念浅析
2015/01/22 PHP
php实现图片上传时添加文字和图片水印技巧
2020/04/18 PHP
php微信公众号开发之答题连闯三关
2018/10/20 PHP
flash javascript之间的通讯方法小结
2008/12/20 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
2014/05/05 Javascript
IE6/IE7中JavaScript json提示缺少标识符、字符串或数字问题处理
2014/12/16 Javascript
IE下使用jQuery重置iframe地址时内存泄露问题解决办法
2015/02/05 Javascript
常用的JavaScript模板引擎介绍
2015/02/28 Javascript
jQuery无刷新切换主题皮肤实例讲解
2015/10/21 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
Bootstrap开关(switch)控件学习笔记分享
2016/05/30 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
React从react-router路由上做登陆验证控制的方法
2018/05/10 Javascript
JavaScript使用indexOf()实现数组去重的方法分析
2018/09/04 Javascript
Nodejs处理异常操作示例
2018/12/25 NodeJs
JavaScript中常用的简洁高级技巧总结
2019/03/10 Javascript
详释JavaScript执行环境与执行栈
2019/04/02 Javascript
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
Python实现爬取知乎神回复简单爬虫代码分享
2015/01/04 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
python如何写个俄罗斯方块
2020/11/06 Python
HTML5重塑Web世界它将如何改变互联网
2012/12/17 HTML / CSS
德国购买门票网站:ADticket.de
2019/10/31 全球购物
新闻编辑自荐信
2013/11/03 职场文书
信息工程学院毕业生推荐信
2013/11/05 职场文书
营销人才自我鉴定范文
2013/12/25 职场文书
客运企业隐患排查工作方案
2014/06/06 职场文书
机械设计及其自动化专业求职信
2014/06/09 职场文书
2015年学校信息技术工作总结
2015/05/25 职场文书
主持人开场白台词
2015/05/29 职场文书
党员观看《筑梦中国》心得体会
2016/01/18 职场文书
PyTorch 如何设置随机数种子使结果可复现
2021/05/12 Python
Python手拉手教你爬取贝壳房源数据的实战教程
2021/05/21 Python