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 相关文章推荐
真正的ZIP文件操作类(php)
Jul 21 PHP
php高级编程-函数-郑阿奇
Jul 04 PHP
php和js如何通过json互相传递数据相关问题探讨
Feb 26 PHP
PHP获取中英混合字符串长度的方法
Jun 07 PHP
PHP执行SQL文件并将SQL文件导入到数据库
Sep 17 PHP
php提高网站效率的技巧
Sep 29 PHP
PHP获取input输入框中的值去数据库比较显示出来
Nov 16 PHP
php连接MSsql server的五种方法总结
Mar 04 PHP
Thinkphp5.0 框架Model模型简单用法分析
Oct 11 PHP
Laravel ORM 数据model操作教程
Oct 21 PHP
php测试kafka项目示例
Feb 06 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
Apr 04 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
php中判断文件存在是用file_exists还是is_file的整理
2012/09/12 PHP
详解PHP中的序列化、反序列化操作
2017/03/21 PHP
类似php的js数组的in_array函数自定义方法
2013/12/27 Javascript
jquery实现的图片点击滚动效果
2014/04/29 Javascript
jQuery常用知识点总结以及平时封装常用函数
2016/02/23 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
2016/03/01 Javascript
利用jquery制作滚动到指定位置触发动画
2016/03/26 Javascript
使用plupload自定义参数实现多文件上传
2016/07/19 Javascript
Bootstrap导航条的使用和理解3
2016/12/14 Javascript
微信小程序 轮播图swiper详解及实例(源码下载)
2017/01/11 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
backbone简介_动力节点Java学院整理
2017/07/14 Javascript
JS实现json对象数组按对象属性排序操作示例
2018/05/18 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
p5.js实现故宫橘猫赏秋图动画
2019/10/23 Javascript
windows实现npm和cnpm安装步骤
2019/10/24 Javascript
vue视频播放插件vue-video-player的具体使用方法
2019/11/08 Javascript
javascript实现切割轮播效果
2019/11/28 Javascript
vue+axios全局添加请求头和参数操作
2020/07/24 Javascript
jQuery实现图片切换效果
2020/10/19 jQuery
[00:57]林俊杰助阵DOTA2亚洲邀请赛
2015/01/28 DOTA
使用Python自动化破解自定义字体混淆信息的方法实例
2019/02/13 Python
Pycharm安装并配置jupyter notebook的实现
2020/05/18 Python
django中ImageField的使用详解
2020/12/21 Python
css3进行截取替代js的substring
2013/09/02 HTML / CSS
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
加拿大鞋子连锁店:Town Shoes
2016/09/26 全球购物
金融行业务员的自我评价
2013/12/13 职场文书
高一地理教学反思
2014/01/18 职场文书
八项规定整改方案
2014/02/21 职场文书
2014年小学班主任工作总结
2014/11/08 职场文书
2014年银行员工工作总结
2014/11/12 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
小平您好观后感
2015/06/09 职场文书
保险公司增员口号
2015/12/25 职场文书
vue使用echarts实现折线图
2022/03/21 Vue.js