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
用PHP实现读取和编写XML DOM代码
Apr 07 PHP
PHP通过session id 实现session共享和登录验证的代码
Jun 03 PHP
php读取富文本的时p标签会出现红线是怎么回事
May 13 PHP
php中unserialize返回false的解决方法
Sep 22 PHP
php文件上传简单实现方法
Jan 24 PHP
PHP中捕获超时事件的方法实例
Feb 12 PHP
WordPress中制作导航菜单的PHP核心方法讲解
Dec 11 PHP
PHP中addcslashes与stripcslashes函数用法分析
Jan 07 PHP
PHP中多线程的两个实现方法
Oct 14 PHP
php reset() 函数指针指向数组中的第一个元素并输出实例代码
Nov 21 PHP
Smarty3配置及入门语法
Feb 22 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代码优化之成员变量获取速度对比
2014/02/28 PHP
写一段简单的PHP建立文件夹代码
2015/01/06 PHP
PHP写的简单数字验证码实例
2017/05/23 PHP
PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
2019/05/21 PHP
jQuery 动态酷效果实现总结
2009/12/27 Javascript
Javascript 实用小技巧
2010/04/07 Javascript
15款优秀的jQuery导航菜单插件分享
2011/07/19 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
如何使用Javascript获取距今n天前的日期
2013/07/08 Javascript
分享JavaScript获取网页关闭与取消关闭的事件
2013/12/13 Javascript
js获取浏览器基本信息大全
2014/11/27 Javascript
jQuery圆形统计图开发实例
2015/01/04 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
利用Vue.js实现求职在线之职位查询功能
2017/07/03 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
2018/02/18 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
Python使用pymongo库操作MongoDB数据库的方法实例
2019/02/22 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
2019/11/08 Python
解决pyshp UnicodeDecodeError的问题
2019/12/06 Python
基于html5 canvas做批改作业的小插件
2020/05/20 HTML / CSS
领先的钻石和订婚戒指零售商:Diamonds-USA
2016/12/11 全球购物
意大利时尚精品店:Nugnes 1920
2020/02/10 全球购物
日语系毕业生推荐信
2013/11/11 职场文书
公司承诺书怎么写
2014/05/24 职场文书
受伤赔偿协议书
2014/09/24 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书
大卫科波菲尔读书笔记
2015/06/30 职场文书
2015年美容师个人工作总结
2015/10/14 职场文书
2016年父亲节寄语
2015/12/04 职场文书
2019新员工心得体会
2019/06/25 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
MySQL性能指标TPS+QPS+IOPS压测
2022/08/05 MySQL