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去掉字符串的最后一个字符附substr()的用法
Mar 23 PHP
PHP代码保护--Zend Guard的使用详解
Jun 03 PHP
用PHP来计算某个目录大小的方法
Apr 01 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
Feb 08 PHP
PHP SPL标准库之SplFixedArray使用实例
May 12 PHP
浅谈COOKIE和SESSION区别
Jul 19 PHP
使用php实现从身份证中提取生日
May 09 PHP
XHProf报告字段含义的解析
May 17 PHP
PHP处理二进制数据的实现方法
Jun 13 PHP
php实现微信扫码支付
Mar 26 PHP
PHP迭代与递归实现无限级分类
Aug 28 PHP
TP5多入口设置实例讲解
Dec 15 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中文本操作的类
2007/03/17 PHP
php 注释规范
2012/03/29 PHP
PHP5中GD库生成图形验证码(有汉字)
2013/07/28 PHP
PHP定时执行任务实现方法详解(Timer)
2015/07/30 PHP
ppk谈JavaScript style属性
2008/10/10 Javascript
通过百度地图获取公交线路的站点坐标的js代码
2012/05/11 Javascript
js获取某月的最后一天日期的简单实例
2013/06/22 Javascript
js使用for循环及if语句判断多个一样的name
2014/09/09 Javascript
jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
2015/08/21 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
Javascript刷新页面的实例
2017/09/23 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
如何从零开始利用js手写一个Promise库详解
2018/04/19 Javascript
微信小程序日历弹窗选择器代码实例
2019/05/09 Javascript
Electron 调用命令行(cmd)
2019/09/23 Javascript
node省市区三级数据性能测评实例分析
2019/11/06 Javascript
vue实现简单瀑布流布局
2020/05/28 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
10款最好的Web开发的 Python 框架
2015/03/18 Python
ansible作为python模块库使用的方法实例
2017/01/17 Python
Python批量更改文件名的实现方法
2017/10/29 Python
keras 多gpu并行运行案例
2020/06/10 Python
python 线程的五个状态
2020/09/22 Python
python中函数返回多个结果的实例方法
2020/12/16 Python
Infababy英国:婴儿推车、Travel System婴儿车和婴儿汽车座椅销售
2018/05/23 全球购物
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
社会发展项目建议书
2014/08/25 职场文书
办护照工作证明
2014/10/01 职场文书
六查六看六改心得体会
2014/10/14 职场文书
2014年班组工作总结
2014/11/20 职场文书
金融专业银行实习证明模板
2014/11/28 职场文书
2015年医生个人工作总结
2015/04/25 职场文书
食品安全责任书范本
2015/05/09 职场文书
2016年班主任培训心得体会
2016/01/07 职场文书
Python获取百度热搜的完整代码
2021/04/07 Python