延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息。

延迟队列的应用场景:

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使用redis的有序集合zset实现延迟队列的更多相关文章

  1. 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)

    redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...

  2. Redis对象——有序集合(ZSet)

    有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序 ...

  3. redis的有序集合ZSET(stored set)

    相关命令 1.ZADD ZADD key-name score member [score member……] 将带有给定分值的成员添加到有序集合里 2.ZREM ZREM  key-name mem ...

  4. redis 有序集合(zset)函数

    redis 有序集合(zset)函数 zAdd 命令/方法/函数 Adds the specified member with a given score to the sorted set stor ...

  5. 9、Redis五大数据类型---有序集合Zset(sorted set)

    一.简介 zset与set异同 相同之处: 都是没有重复元素的字符串集合 不同之处: 有序集合zset的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排 ...

  6. [PHP] PHP多个进程配合redis的有序集合实现大文件去重

    1.对一个大文件比如我的文件为 -rw-r--r--  1 ubuntu ubuntu  9.1G Mar  1 17:53 2018-12-awk-uniq.txt 2.使用split命令切割成10 ...

  7. Redis 操作有序集合数据

    Redis 操作有序集合数据: > zadd names "Tom" // zadd 用于往有序集合中添加元素,其中 1 在 Redis 中称为 score(分数),用来进行 ...

  8. python 操作redis之——有序集合(sorted set) (七)

    #coding:utf8 import redis r =redis.Redis(host=") 1.Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员已经是有序 ...

  9. Redis入门到高可用(九)——有序集合zset

    一.数据结构 集合与有序集合,列表与有序集合的对比 二.主要API zadd 将一个或多个 member 元素及其 score 值加入到有序集 key 当中. zrem 移除有序集 key 中的一个或 ...

随机推荐

  1. CentOS安装MySQL的完整步骤

    1.官方安装文档 http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ 2.下载 Mysql yum包 http://dev.mysql.co ...

  2. 使用Keras训练大规模数据集

    官方提供的.flow_from_directory(directory)函数可以读取并训练大规模训练数据,基本可以满足大部分需求.但是在有些场合下,需要自己读取大规模数据以及对应标签,下面提供一种方法 ...

  3. HTTPS的内网访问和访问外网

    https://launchpad.support.sap.com/#/notes/2461900 https://wiki.scn.sap.com/wiki/display/Security/Tro ...

  4. python2.7 Cheetah You don't have the C version of NameMapper installed

    问题:You don't have the C version of NameMapper installed sudo vi /usr/lib/python2.7/site-packages/Che ...

  5. 系统设计与架构笔记:ETL工具开发和设计的建议

    最近项目组里想做一个ETL数据抽取工具,这是一个研发项目,但是感觉公司并不是特别重视,不重视不是代表它不重要,而是可能不会对这个项目要求太高,能满足我们公司的小需求就行,想从这个项目里衍生出更多的东西 ...

  6. asp.net ajax get 调用(和post不一样,直接返回json才行,否则报错;post不能返回json)

    <script type="text/javascript" > $(document).ready(function () { $('#Label1').click( ...

  7. 对java开发者来说比较好网站客推荐

    阿里巴巴开发者梁飞的博客地址:http://javatar.iteye.com/ 并发编程网:http://ifeve.com/ 开发者头条:https://toutiao.io/ importNew ...

  8. Java学习随笔(2)--爬虫--天气预报

    public class Spiderweather { public static void main(String[] args) { List<String> list = null ...

  9. centos 7安装vnc服务端&vnc客户端连接

    前言 工作需求,需要用到vnc,介绍一下相关内容. 安装vnc服务端 在执行其他相关的之前,需要先安装一下vnc的服务端,命令如下: yum install tigervnc-server 配置vnc ...

  10. ensureCapacity增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。

    扩容原则: 若参数值大于底层数组长度的1.5倍,则数组的长度就扩容为这个参数值:若小于底层数组长度的1.5倍,则数组长度就扩容为底层数组长度的1.5倍. ensureCapacity提高效率 fina ...