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 相关文章推荐
一个用于mysql的数据库抽象层函数库
Oct 09 PHP
php&amp;mysql 日期操作小记
Feb 27 PHP
php中长文章分页显示实现代码
Sep 29 PHP
PHP中的gzcompress、gzdeflate、gzencode函数详解
Jul 29 PHP
PHP多线程编程之管道通信实例分析
Mar 07 PHP
php基础设计模式大全(注册树模式、工厂模式、单列模式)
Aug 31 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
Dec 08 PHP
php中bind_param()函数用法分析
Mar 28 PHP
PHP实现的分页类定义与用法示例
Jul 05 PHP
PHP实现简易计算器功能
Aug 28 PHP
laravel实现简单用户权限的示例代码
May 28 PHP
PHP并发场景的三种解决方案代码实例
Feb 27 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使用Smarty的相关注意事项及访问变量的几种方式
2011/12/08 PHP
php setcookie函数的参数说明及其用法
2014/04/20 PHP
ThinkPHP在新浪SAE平台的部署实例
2014/10/31 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
PHP中使用foreach()遍历二维数组的简单实例
2016/06/13 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
ecshop适应在PHP7的修改方法解决报错的实现
2016/11/01 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
PHP中PDO事务处理操作示例
2018/05/02 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
你需要知道的JavsScript可以做什么?
2007/06/29 Javascript
项目实践之javascript技巧
2007/12/06 Javascript
js字符编码函数区别分析
2008/06/05 Javascript
jQuery ctrl+Enter shift+Enter实现代码
2010/02/07 Javascript
jquery 学习笔记一
2010/04/07 Javascript
input 和 textarea 输入框最大文字限制的jquery插件
2011/10/27 Javascript
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
2012/10/12 Javascript
jquery ajax请求实例深入解析
2012/11/26 Javascript
微信JS接口汇总及使用详解
2015/01/09 Javascript
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
jQuery 导航自动跟随滚动的实现代码
2018/05/30 jQuery
javascript中floor使用方法总结
2019/02/02 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
2019/09/27 Javascript
[08:47]2018国际邀请赛 OG战队举杯时刻
2018/08/29 DOTA
Python3实现并发检验代理池地址的方法
2016/09/18 Python
python pandas.DataFrame选取、修改数据最好用.loc,.iloc,.ix实现
2018/06/11 Python
opencv 阈值分割的具体使用
2020/07/08 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
Watch Station官方网站:世界一流的手表和智能手表
2020/01/05 全球购物
女大学生毕业找工作的自我评价
2013/10/03 职场文书
善意的谎言事例
2014/02/15 职场文书
专项法律服务方案
2014/06/11 职场文书
施工安全责任书范本
2014/07/24 职场文书
爱心助学感谢信
2015/01/21 职场文书
贪污检举信范文
2015/03/02 职场文书
安全伴我行主题班会
2015/08/13 职场文书