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 的 __FILE__ 常量
Jan 15 PHP
PHP远程连接MYSQL数据库非常慢的解决方法
Jul 05 PHP
PHP array 的加法操作代码
Jul 24 PHP
php写的AES加密解密类分享
Jun 20 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
Jul 25 PHP
PHP生成随机字符串(3种方法)
Sep 25 PHP
PHP的反射机制实例详解
Mar 29 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
Jul 19 PHP
PHP实现更改hosts文件的方法示例
Aug 08 PHP
PHP使用ajax的post方式下载excel文件简单示例
Aug 06 PHP
Laravel实现ORM带条件搜索分页
Oct 24 PHP
PHP防止sql注入小技巧之sql预处理原理与实现方法分析
Dec 13 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数据库连接
2006/10/09 PHP
php 生成静态页面的办法与实现代码详细版
2010/02/15 PHP
PHP开发中四种查询返回结果分析
2011/01/02 PHP
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
2013/02/14 PHP
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
PHP设置Cookie的HTTPONLY属性方法
2017/02/09 PHP
PHP多进程通信-消息队列使用
2019/03/08 PHP
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
Extjs入门之动态加载树代码
2010/04/09 Javascript
html中table数据排序的js代码
2011/08/09 Javascript
jQuery EasyUI API 中文文档 - ComboBox组合框
2011/10/07 Javascript
javascript中的parseInt和parseFloat区别
2013/07/12 Javascript
jquery.validate使用时遇到的问题
2015/05/25 Javascript
JavaScript——DOM操作——Window.document对象详解
2016/07/14 Javascript
bootstrap模态框远程示例代码分享
2017/05/22 Javascript
JavaScript实现兼容IE6的收起折叠与展开效果实例
2017/09/20 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
详解javascript中的变量提升和函数提升
2018/05/24 Javascript
js canvas实现橡皮擦效果
2018/12/20 Javascript
JavaScript console的使用方法实例分析
2020/04/28 Javascript
JS实现小米轮播图
2020/09/21 Javascript
JavaScript枚举选择jquery插件代码实例
2020/11/17 jQuery
python求素数示例分享
2014/02/16 Python
Python字符和字符值(ASCII或Unicode码值)转换方法
2015/05/21 Python
pygame实现弹力球及其变速效果
2017/07/03 Python
python实现redis三种cas事务操作
2017/12/19 Python
python实现多层感知器
2019/01/18 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
python 有效的括号的实现代码示例
2019/11/11 Python
Perfume’s Club法国站:购买香水和化妆品
2019/05/02 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
餐厅筹备计划书
2014/04/25 职场文书
企业宣传标语
2014/06/09 职场文书
小学生交通安全寄语
2015/02/27 职场文书
法院答辩状格式
2015/05/22 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js