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 相关文章推荐
使用adodb lite解决问题
Dec 31 PHP
php 结果集的分页实现代码
Mar 10 PHP
PHP中防止SQL注入攻击和XSS攻击的两个简单方法
Apr 15 PHP
PHP网站备份程序代码分享
Jun 10 PHP
php 文章调用类代码
Aug 11 PHP
解析php中eclipse 用空格替换 tab键
Jun 24 PHP
Laravel 5 学习笔记
Mar 06 PHP
PHP加密解密类实例分析
Apr 20 PHP
PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)
Sep 22 PHP
Smarty简单生成表单元素的方法示例
May 23 PHP
微信开发之php表单微信中自动提交两次问题解决办法
Jan 08 PHP
PHP利用curl发送HTTP请求的实例代码
Jul 09 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
批量修改RAR文件注释的php代码
2010/11/20 PHP
php连接数据库代码应用分析
2011/05/29 PHP
PHP使用递归生成文章树
2015/04/21 PHP
基于PHP实现的事件机制实例分析
2015/06/18 PHP
详解PHP+AJAX无刷新分页实现方法
2015/11/03 PHP
PHPExcel导出2003和2007的excel文档功能示例
2017/01/04 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
2017/02/24 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
2017/05/05 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
JavaScript 计算当天是本年本月的第几周
2009/03/22 Javascript
在jquery boxy中添加百度地图坐标拾取注意流程
2014/04/03 Javascript
Javascript实现禁止输入中文或英文的例子
2014/12/09 Javascript
js获取当前日期时间及其它操作汇总
2015/04/17 Javascript
Javascript中实现String.startsWith和endsWith方法
2015/06/10 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
JQuery点击事件回到页面顶部效果的实现代码
2016/05/24 Javascript
jQuery仿京东商城楼梯式导航定位菜单
2016/07/25 Javascript
javascript简单进制转换实现方法
2016/11/24 Javascript
vue-cli+webpack记事本项目创建
2017/04/01 Javascript
JavaScript变量Dom对象的所有属性
2020/04/30 Javascript
Django与遗留的数据库整合的方法指南
2015/07/24 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
python实现FTP服务器服务的方法
2017/04/11 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
2019/06/18 Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
2020/03/18 Python
Python进程的通信Queue、Pipe实例分析
2020/03/30 Python
python 读取串口数据的示例
2020/11/09 Python
python 实现倒计时功能(gui界面)
2020/11/11 Python
一款利用纯css3实现的360度翻转按钮的实例教程
2014/11/05 HTML / CSS
CSS3中引入多种自定义字体font-face
2020/06/12 HTML / CSS
HTML5中的进度条progress元素简介及兼容性处理
2016/06/02 HTML / CSS
酒店管理自荐信
2013/10/23 职场文书
保证书格式范文
2014/04/28 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
党员转正大会主持词
2015/07/02 职场文书
导游词之海南天涯海角
2019/12/05 职场文书