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.MVC的模板标签系统(三)
Sep 05 PHP
php生成的html meta和link标记在body标签里 顶部有个空行
May 18 PHP
mysql数据库差异比较的PHP代码
Feb 05 PHP
php日历制作代码分享
Jan 20 PHP
PHP获取mysql数据表的字段名称和详细信息的方法
Sep 27 PHP
php实现计数器方法小结
Jan 05 PHP
ecshop 2.72如何修改后台访问地址
Mar 03 PHP
php实现约瑟夫问题的方法小结
Mar 23 PHP
PHP正则匹配日期和时间(时间戳转换)的实例代码
Dec 14 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 PHP
TP5框架安全机制实例分析
Apr 05 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
LotusPhp笔记之:基于ObjectUtil组件的使用分析
2013/05/06 PHP
PHP goto语句简介和使用实例
2014/03/11 PHP
php强制更新图片缓存的方法
2015/02/11 PHP
java微信开发之上传下载多媒体文件
2016/06/24 PHP
jquery.alert 弹出式复选框实现代码
2009/06/15 Javascript
js 获取计算后的样式写法及注意事项
2013/02/25 Javascript
js实现文本框支持加减运算的方法
2015/08/19 Javascript
JavaScript toUpperCase()方法使用详解
2016/08/26 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
js仿iphone秒表功能 计算平均数
2017/01/11 Javascript
three.js绘制地球、飞机与轨迹的效果示例
2017/02/28 Javascript
JavaScript实现form表单的多文件上传
2020/03/27 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
2017/07/24 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
使用angularjs.foreach时return的问题解决
2018/09/30 Javascript
JS实现十分钟倒计时代码实例
2018/10/18 Javascript
Javascript之高级数组API的使用实例
2019/03/08 Javascript
JS html事件冒泡和事件捕获操作示例
2019/05/01 Javascript
JS实现前端动态分页码代码实例
2020/06/02 Javascript
JS实现简单打字测试
2020/06/24 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
jQuery实现推拉门效果
2020/10/19 jQuery
Python 时间处理datetime实例
2008/09/06 Python
python33 urllib2使用方法细节讲解
2013/12/03 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
Python模块_PyLibTiff读取tif文件的实例
2020/01/13 Python
Python selenium模拟手动操作实现无人值守刷积分功能
2020/05/13 Python
django正续或者倒序查库实例
2020/05/19 Python
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
汽车维修专业自荐书
2014/05/26 职场文书
体育运动口号
2014/06/09 职场文书
元旦联欢晚会主持词
2015/07/01 职场文书
德能勤绩工作总结
2015/08/11 职场文书
聘任书的格式及模板
2019/10/28 职场文书
教你利用Selenium+python自动化来解决pip使用异常
2021/05/20 Python
浏览器常用基本操作之python3+selenium4自动化测试(基础篇3)
2021/05/21 Python