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的博客ping服务代码
Feb 04 PHP
PHP之短标签开启设置
Jun 17 PHP
php中自定义函数dump查看数组信息类似var_dump
Jan 27 PHP
php实现的发送带附件邮件类实例
Sep 22 PHP
PHP使用pcntl_fork实现多进程下载图片的方法
Dec 16 PHP
Yii扩展组件编写方法实例分析
Jun 29 PHP
深入理解PHP类的自动载入机制
Sep 16 PHP
thinkphp整合微信支付代码分享
Nov 24 PHP
PHP微信分享开发详解
Jan 14 PHP
phpinfo无法显示的原因及解决办法
Feb 15 PHP
Laravel获取所有的数据库表及结构的方法
Oct 10 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
Nov 26 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
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
PHP中创建图像并绘制文字的例子
2014/11/19 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
写了10年的Javascript也未必全了解的连续赋值运算
2011/03/25 Javascript
Fixie.js 自动填充内容的插件
2012/06/28 Javascript
Js实现双击鼠标自动滚动屏幕的示例代码
2013/12/14 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
2014/02/13 Javascript
javascript关于继承的用法汇总
2014/12/20 Javascript
AngularJS中$http服务常用的应用及参数
2016/08/22 Javascript
input框中的name和id的区别
2016/11/16 Javascript
javascript闭包功能与用法实例分析
2017/04/06 Javascript
vue+iview写个弹框的示例代码
2017/12/05 Javascript
微信小程序点击view动态添加样式过程解析
2020/01/21 Javascript
python网络编程之文件下载实例分析
2015/05/20 Python
使用python实现接口的方法
2017/07/07 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
Python在for循环中更改list值的方法【推荐】
2018/08/17 Python
关于python多重赋值的小问题
2019/04/17 Python
python与字符编码问题
2019/05/24 Python
python实现关闭第三方窗口的方法
2019/06/28 Python
Python字符串split及rsplit方法原理详解
2020/06/29 Python
利用python绘制中国地图(含省界、河流等)
2020/09/21 Python
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
如何通过 CSS 写出火焰效果
2021/03/24 HTML / CSS
表彰会主持词
2014/03/26 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
对外汉语专业大学生职业生涯规划范文
2014/09/13 职场文书
2014年保洁员工作总结
2014/11/19 职场文书
违纪检讨书
2015/01/27 职场文书
学校中秋节活动总结
2015/03/23 职场文书
幼儿园小班开学寄语(2016秋季)
2015/12/03 职场文书
爱岗敬业先进典型事迹材料(2016推荐版)
2016/02/26 职场文书
高一作文之暖冬
2019/11/09 职场文书
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js
纯html+css实现打字效果
2021/08/02 HTML / CSS
动画电影《龙珠超 超级英雄》延期上映
2022/03/20 日漫