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 文件类型判断代码
Mar 13 PHP
php数组函数序列之array_sum() - 计算数组元素值之和
Oct 29 PHP
深入了解PHP类Class的概念
Jun 14 PHP
浅析PHP原理之变量(Variables inside PHP)
Aug 09 PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
Sep 28 PHP
php加密解密字符串示例
Oct 13 PHP
php解决DOM乱码的方法示例代码
Nov 20 PHP
php获取开始与结束日期之间所有日期的方法
Nov 29 PHP
简单实现PHP留言板功能
Dec 21 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
PHP进阶学习之反射基本概念与用法分析
Jun 18 PHP
如何在PHP环境中使用ProtoBuf数据格式
Jun 19 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获取数组长度的方法(有实例)
2013/10/27 PHP
PHP实现的构造sql语句类实例
2016/02/03 PHP
php版微信开发之接收消息,自动判断及回复相应消息的方法
2016/09/23 PHP
ThinkPHP框架实现的MySQL数据库备份功能示例
2018/05/24 PHP
PHP实现微信退款功能
2018/10/02 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
详解PHP 7.4 中数组延展操作符语法知识点
2019/07/19 PHP
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
2010/04/14 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
图片懒加载imgLazyLoading.js使用详解
2020/09/15 Javascript
vue cli2.0单页面title修改方法
2018/06/07 Javascript
Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
2018/10/28 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
vue 递归组件的简单使用示例
2021/01/14 Vue.js
在nodejs中创建child process的方法
2021/01/26 NodeJs
[02:30]联想杯DOTA2完美世界全国高校联赛—北京站现场
2015/11/16 DOTA
Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
2008/09/06 Python
Python+MongoDB自增键值的简单实现
2016/11/04 Python
python版本坑:md5例子(python2与python3中md5区别)
2017/06/20 Python
TensorFlow2.0:张量的合并与分割实例
2020/01/19 Python
Python爬取365好书中小说代码实例
2020/02/28 Python
Python类class参数self原理解析
2020/11/19 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
日本土著品牌,综合型购物网站:Cecile
2016/08/23 全球购物
小学红领巾广播稿(3篇)
2014/09/13 职场文书
副总经理党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/06 职场文书
2014年行风建设工作总结
2014/12/01 职场文书
2016七夕情人节寄语
2015/12/04 职场文书
为什么不建议在go项目中使用init()
2021/04/12 Golang
Python打包exe时各种异常处理方案总结
2021/05/18 Python
利用Python多线程实现图片下载器
2022/03/25 Python
MySQL 数据库范式化设计理论
2022/04/22 MySQL