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新手谈谈我的学习心得
Feb 25 PHP
PHP 文件扩展名 获取函数
Jun 03 PHP
php中利用str_pad函数生成数字递增形式的产品编号
Sep 30 PHP
浅谈php+phpStorm+xdebug配置方法
Sep 17 PHP
PHP实现限制IP访问的方法
Apr 20 PHP
Yii2实现自定义独立验证器的方法
May 05 PHP
PHP实现文件上传功能实例代码
May 18 PHP
PHP环形链表实现方法示例
Sep 15 PHP
PHP如何实现阿里云短信sdk灵活应用在项目中的方法
Jun 14 PHP
在TP5数据库中四个字段实现无限分类的示例
Oct 18 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 PHP
Laravel框架数据库迁移操作实例详解
Apr 06 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
一个MYSQL操作类
2006/11/16 PHP
有关PHP中MVC的开发经验分享
2012/05/17 PHP
php有道翻译api调用方法实例
2014/12/22 PHP
PHP下载远程图片并保存到本地方法总结
2016/01/22 PHP
js 函数调用模式小结
2011/12/26 Javascript
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
js实现动态改变字体大小代码
2014/01/02 Javascript
JS对文本框值的判断示例
2014/03/10 Javascript
javascript if条件判断方法小结
2014/05/17 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
jquery实现兼容IE8的异步上传文件
2015/06/15 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
EasyUI Pagination 分页的两种做法小结
2016/07/09 Javascript
AngularJS入门教程之静态模板详解
2016/08/18 Javascript
Vuejs第十篇之vuejs父子组件通信
2016/09/06 Javascript
webpack2.0搭建前端项目的教程详解
2017/04/05 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
javascript实现循环广告条效果
2017/12/12 Javascript
微信小程序websocket实现聊天功能
2020/03/30 Javascript
浅谈Angular 观察者模式理解
2018/11/01 Javascript
Python列表list数组array用法实例解析
2014/10/28 Python
Python正则表达式匹配HTML页面编码
2015/04/08 Python
python3写爬取B站视频弹幕功能
2017/12/22 Python
python实现学生管理系统
2018/01/11 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
python opencv实现图像边缘检测
2019/04/29 Python
将数据集制作成VOC数据集格式的实例
2020/02/17 Python
Vilebrequin欧洲官网:法国豪华泳装品牌(男士沙滩裤)
2018/04/14 全球购物
安全检查与奖惩制度
2014/01/23 职场文书
超市开学活动方案
2014/03/01 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
商务英语专业大学生职业生涯规划书
2014/09/14 职场文书
2015年护士长个人工作总结
2015/04/24 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
导游词之沈阳植物园
2019/11/30 职场文书