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学习之PHP变量
Oct 09 PHP
PHP 采集获取指定网址的内容
Jan 05 PHP
php flv视频时间获取函数
Jun 29 PHP
php输出表格的实现代码(修正版)
Dec 29 PHP
php中OR与|| AND与&amp;&amp;的区别总结
Oct 26 PHP
使用PHP破解防盗链图片的一个简单方法
Jun 07 PHP
php遍历数组的4种方法总结
Jul 05 PHP
php中instanceof 与 is_a()区别分析
Mar 03 PHP
php中namespace use用法实例分析
Jan 22 PHP
PHP实现活动人选抽奖功能
Apr 19 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
Apr 26 PHP
如何用RabbitMQ和Swoole实现一个异步任务系统
May 29 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 生成WML页面方法详解
2009/08/09 PHP
PHPWind 发帖回帖Api PHP版打包下载
2010/02/08 PHP
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
2014/06/23 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
php判断数组是否为空的实例方法
2020/05/10 PHP
window.ActiveXObject使用说明
2010/11/08 Javascript
javascript 闭包疑问
2010/12/30 Javascript
基于jQuery实现表格数据的动态添加与统计的代码
2011/01/31 Javascript
中文路径导致unitpngfix.js不正常的解决方法
2013/06/26 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
JQuery文字列表向上滚动的代码
2013/11/13 Javascript
页面装载js及性能分析方法介绍
2014/03/21 Javascript
jQuery实现摸拟alert提示框
2016/05/22 Javascript
JavaScript 闭包机制详解及实例代码
2016/10/10 Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
2016/11/02 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
ES6 javascript的异步操作实例详解
2017/10/30 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
webpack4 从零学习常用配置(小结)
2019/05/28 Javascript
[09:37]2018DOTA2国际邀请赛寻真——不懈追梦的Team Serenity
2018/08/13 DOTA
Python中自定义函数的教程
2015/04/27 Python
在Python中用keys()方法返回字典键的教程
2015/05/21 Python
python实现图片变亮或者变暗的方法
2015/06/01 Python
Python 一键制作微信好友图片墙的方法
2019/05/16 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
详解python中各种文件打开模式
2020/01/19 Python
解决Tensorflow 使用时cpu编译不支持警告的问题
2020/02/03 Python
Keras设置以及获取权重的实现
2020/06/19 Python
html5 利用canvas手写签名并保存的实现方法
2018/07/12 HTML / CSS
九年级科学教学反思
2014/01/29 职场文书
党员群众路线对照检查材料
2014/08/31 职场文书
法院反腐倡廉心得体会
2014/09/09 职场文书
村官个人总结范文
2015/03/03 职场文书
小学数学教师研修日志
2015/11/13 职场文书
CSS 伪元素::marker详解
2021/06/26 HTML / CSS