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 上传文件类型判断函数(避免上传漏洞 )
Jun 08 PHP
PHP引用符&amp;的用法详细解析
Aug 22 PHP
php实现过滤表单提交中html标签的方法
Oct 17 PHP
php树型类实例
Dec 05 PHP
PHP实现加强版加密解密类实例
Jul 29 PHP
smarty中常用方法实例总结
Aug 07 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
Dec 18 PHP
PHP PDOStatement::columnCount讲解
Jan 30 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
Mar 12 PHP
Yii框架ACF(accessController)简单权限控制操作示例
Apr 26 PHP
Yii 框架使用Forms操作详解
May 18 PHP
phpstorm激活码2020附使用详细教程
Sep 25 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版(1)
2006/10/09 PHP
十幅图告诉你什么是PHP引用
2015/02/22 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
2015/06/23 PHP
php处理静态页面:页面设置缓存时间实例
2017/06/22 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
JavaScript 无符号右移赋值操作
2009/04/17 Javascript
浅谈JavaScript 框架分类
2014/11/10 Javascript
jQuery浏览器CSS3特写兼容实例
2015/01/19 Javascript
jQuery实现渐变下拉菜单的简单方法
2015/03/11 Javascript
jQuery实现的自动加载页面功能示例
2016/09/04 Javascript
vue-router 学习快速入门
2017/03/01 Javascript
超简单的Vue.js环境搭建教程
2017/03/17 Javascript
解决AngualrJS页面刷新导致异常显示问题
2017/04/20 Javascript
微信小程序学习之数据处理详解
2017/07/05 Javascript
Vue封装Swiper实现图片轮播效果
2018/02/06 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
微信小程序实现批量倒计时功能
2020/11/01 Javascript
vue 开发企业微信整合案例分析
2019/12/02 Javascript
python复制文件代码实现
2013/12/23 Python
Python返回真假值(True or False)小技巧
2015/04/10 Python
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Scrapy框架使用的基本知识
2018/10/21 Python
python多进程控制学习小结
2018/10/31 Python
Django Channels 实现点对点实时聊天和消息推送功能
2019/07/17 Python
python定位xpath 节点位置的方法
2019/08/27 Python
python实现LRU热点缓存及原理
2019/10/29 Python
python GUI库图形界面开发之PyQt5窗口背景与不规则窗口实例
2020/02/25 Python
Python3读取和写入excel表格数据的示例代码
2020/06/09 Python
python字符串的index和find的区别详解
2020/06/20 Python
CSS3 对过渡(transition)进行调速以及延时
2020/10/21 HTML / CSS
详解前端HTML5几种存储方式的总结
2016/12/27 HTML / CSS
单身旅行者的单身假期:Just You
2018/04/08 全球购物
输入N,打印N*N矩阵
2012/02/20 面试题
国际残疾人日广播稿范文
2014/10/09 职场文书
通知范文怎么写
2015/04/16 职场文书
保密法制宣传月活动总结
2015/05/07 职场文书