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 相关文章推荐
文件上传类
Oct 09 PHP
phpmyadmin的#1251问题
Nov 25 PHP
并发下常见的加锁及锁的PHP具体实现代码
Oct 12 PHP
深入php多态的实现详解
Jun 09 PHP
windows下配置apache+php+mysql时出现问题的处理方法
Jun 20 PHP
PHP中的插件机制原理和实例
Jul 08 PHP
PHP 生成N个不重复的随机数
Jan 21 PHP
PHP 获取ip地址代码汇总
Jul 05 PHP
PHP中的表达式简述
May 29 PHP
PHP学习记录之数组函数
Jun 01 PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
Dec 04 PHP
PHP全局使用Laravel辅助函数dd
Dec 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
php mysql索引问题
2008/06/07 PHP
提高PHP性能的编码技巧以及性能优化详细解析
2013/08/24 PHP
php按字符无乱码截取中文的方法
2015/03/27 PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
2020/04/06 PHP
基于PHP实现用户登录注册功能的详细教程
2020/08/04 PHP
prototype 1.5相关知识及他人笔记
2006/12/16 Javascript
JavaScript返回上一页的三种方法及区别介绍
2015/07/04 Javascript
js实现的页面矩阵图形变换特效
2016/01/26 Javascript
全面理解JavaScript中的闭包
2016/05/12 Javascript
JS中用try catch对代码运行的性能影响分析
2016/12/26 Javascript
Bootstrap模态窗口源码解析
2017/02/08 Javascript
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
2017/03/28 NodeJs
Javascript循环删除数组中元素的几种方法示例
2017/05/18 Javascript
微信小程序实现蒙版弹窗效果
2018/11/01 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
google广告之另类js调用实现代码
2020/08/22 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
[55:45]LGD vs OG 2019国际邀请赛淘汰赛 胜者组 BO3 第三场 8.24
2019/09/10 DOTA
Python中用max()方法求最大值的介绍
2015/05/15 Python
Django中使用group_by的方法
2015/05/26 Python
Python基于PyGraphics包实现图片截取功能的方法
2017/12/21 Python
详解Python3中setuptools、Pip安装教程
2019/06/18 Python
django 信号调度机制详解
2019/07/19 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
Python实现ATM系统
2020/02/17 Python
Python抓包程序mitmproxy安装和使用过程图解
2020/03/02 Python
使用css3实现的tab选项卡代码分享
2014/12/09 HTML / CSS
英国度假别墅预订:Sykes Cottages
2017/06/12 全球购物
应届生服装设计自我评价
2013/09/20 职场文书
师范应届生语文教师求职信
2013/10/29 职场文书
心得体会怎么写
2013/12/30 职场文书
初中开学典礼新闻稿
2015/07/17 职场文书
Python文件的操作示例的详细讲解
2021/04/08 Python
浅谈mysql返回Boolean类型的几种情况
2021/06/04 MySQL