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之COOKIE支持详解
Sep 20 PHP
php中用于检测一个地理IP地址是否可用的代码
Feb 19 PHP
如何批量替换相对地址为绝对地址(利用bat批处理实现)
May 27 PHP
PHP 实现explort() 功能的详解
Jun 20 PHP
PHP程序员不应该忽略的3点
Oct 09 PHP
PHP实现搜索地理位置及计算两点地理位置间距离的实例
Jan 08 PHP
PHP自定义函数获取URL中一级域名的方法
Aug 23 PHP
利用php抓取蜘蛛爬虫痕迹的示例代码
Sep 30 PHP
PHP实现根据数组的值进行分组的方法
Apr 20 PHP
PHP实现的猴王算法(猴子选大王)示例
Apr 30 PHP
PHP网站常见安全漏洞,及相应防范措施总结
Mar 01 PHP
PHP安装扩展mcrypt以及相关依赖项深入讲解
Mar 04 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获取一定范围内取N个不重复的随机数
2016/05/28 PHP
php下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
由JavaScript技术实现的web小游戏(不含网游)
2010/06/12 Javascript
jquery 中多条件选择器,相对选择器,层次选择器的区别
2012/07/03 Javascript
定义JavaScript二维数组采用定义数组的数组来实现
2012/12/09 Javascript
用js实现控件的隐藏及style.visibility的使用
2013/06/14 Javascript
JavaScript中exec函数用法实例分析
2015/06/08 Javascript
javascript正则表达式中分组详解
2016/07/17 Javascript
JS 数字转换为大写金额的简单实例
2016/08/04 Javascript
新手学习前端之js模仿淘宝主页网站
2016/10/31 Javascript
Bootstrap3 图片(响应式图片&amp;图片形状)
2017/01/04 Javascript
jQuery插件FusionCharts绘制的2D双柱状图效果示例【附demo源码】
2017/05/13 jQuery
神级程序员JavaScript300行代码搞定汉字转拼音
2017/05/20 Javascript
浅谈关于axios和session的一些事
2017/07/13 Javascript
jQuery 实时保存页面动态添加的数据的示例
2017/08/14 jQuery
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
2019/03/09 Javascript
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
JS async 函数的含义和用法实例总结
2020/04/08 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
NetworkX之Prim算法(实例讲解)
2017/12/22 Python
python获取酷狗音乐top500的下载地址 MP3格式
2018/04/17 Python
python在文本开头插入一行的实例
2018/05/02 Python
python多线程并发实例及其优化
2019/06/27 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
PyTorch如何搭建一个简单的网络
2020/08/24 Python
加拿大品牌鞋包连锁店:Little Burgundy
2021/02/28 全球购物
银行求职推荐信范文
2013/11/30 职场文书
母亲节演讲稿范文
2014/01/02 职场文书
广播体操口号
2014/06/18 职场文书
2015安全保卫工作总结
2015/04/25 职场文书
妇联2016年六一国际儿童节活动总结
2016/04/06 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
mysql 数据插入优化方法之concurrent_insert
2021/07/01 MySQL