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 Document 代码注释规范
Apr 13 PHP
php.ini-dist 和 php.ini-recommended 的区别介绍(方便开发与安全的朋友)
Jul 01 PHP
php防注入及开发安全详细解析
Aug 09 PHP
Laravel框架学习笔记(一)环境搭建
Oct 15 PHP
php jsonp单引号转义
Nov 23 PHP
PHP中捕获超时事件的方法实例
Feb 12 PHP
基于thinkPHP类的插入数据库操作功能示例
Jan 06 PHP
Yii输入正确验证码却验证失败的解决方法
Jun 06 PHP
详解yii2使用多个数据库的案例
Jun 16 PHP
Laravel框架分页实现方法分析
Jun 12 PHP
PHP中引用类型和值类型功能与用法示例
Feb 26 PHP
ThinkPHP 5.x远程命令执行漏洞复现
Sep 23 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
Home Coffee Roasting
2021/03/03 咖啡文化
php mysql PDO 查询操作的实例详解
2017/09/23 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
什么是JavaScript
2009/08/13 Javascript
使用Mootools动态添加Css样式表代码,兼容各浏览器
2011/12/12 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
js文本框输入点回车触发确定兼容IE、FF等
2013/11/19 Javascript
使用JavaScript获取电池状态的方法
2014/05/03 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
深入探讨前端框架react
2015/12/09 Javascript
JavaScript在form表单中使用button按钮实现submit提交方法
2017/01/23 Javascript
H5实现中奖记录逐行滚动切换效果
2017/03/13 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
JS+WCF实现进度条实时监测数据加载量的方法详解
2017/12/19 Javascript
JavaScript设计模式之职责链模式应用示例
2018/08/07 Javascript
JQuery Ajax如何实现注册检测用户名
2020/09/25 jQuery
python显示生日是星期几的方法
2015/05/27 Python
python编程实现希尔排序
2017/04/13 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
python统计中文字符数量的两种方法
2019/01/31 Python
对django views中 request, response的常用操作详解
2019/07/17 Python
Matplotlib绘制雷达图和三维图的示例代码
2020/01/07 Python
tensorflow求导和梯度计算实例
2020/01/23 Python
python输出第n个默尼森数的实现示例
2020/03/08 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
2020/03/09 Python
Python3爬虫中pyspider的安装步骤
2020/07/29 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
2020/12/28 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
全球航班旅行搜索网站:Cheapflights
2017/05/19 全球购物
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
瑞士隐形眼镜和护理产品网上商店:Linsenklick
2019/10/21 全球购物
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
小学生清明节演讲稿
2014/09/05 职场文书
党员干部形式主义个人整改措施
2014/09/17 职场文书
《桂花雨》教学反思
2016/02/19 职场文书