php redis zset 延迟队列_php使用redis的有序集合zset实现延迟队列

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

延迟队列的应用场景:

1、新用户注册,10分钟后发送邮件或站内信。

2、用户下单后,30分钟未支付,订单自动作废。

我们通过redis的有序集合zset来实现简单的延迟队列,将消息数据序列化,作为zset的value,把消息处理时间作为score,每次通过zRangeByScore获取一条消息进行处理。

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脚本,用来处理队列中的任务。

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);

}

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

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

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

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

redis的有序集合ZSET(stored set)

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

redis 有序集合(zset)函数

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

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

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

Redis 操作有序集合数据

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

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

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

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

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

redis:php-redis中有序集合 zset的使用

ZSET(stored set) 和 set 一样是字符串的集合,不同的是每个元素都会关联一个 double 类型的 score .实现使用的是 skip list 和 hash table , sk ...

随机推荐

ZeroMQ接口函数之 :zmq_msg_more - 指出是不是还有更多的消息部分可以接收

ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_msg_more zmq_msg_more(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...

js 一搬问题汇总

--有时无法进行js调试,在浏览器中设置启用脚本调试就可以了

TFS 与活动目录AD(Active Directory)的同步机制

TFS用户管理机制 TFS系统与企业域服务器用户系统(或本地计算机用户系统)高度集成在一起,使用域服务器验证系统用户的账户和密码,从而在企业中实现单一用户,单点登录.也就是说,TFS系统自身并没有用户 ...

webpack 多入口配置

同事套搭建vue项目,个人推荐了VUE官网的vue-cil的方式,http://cn.vuejs.org/guide/application.html 顺着官网的操作,我们可以本地测试起我们的项目 n ...

学习pthreads,给线程传递多个參数

上篇博文中.boss线程给其它线程传递的仅仅有一个參数,那么假如是多个參数呢?怎么传递呢?也许你会有这种疑问,带着这个疑问,我们进入本文的世界,这里传递多个參数,採用结构体,为什么呢?由于结构体里能够 ...

驱动之路四------adc驱动(input设备)

开发板:smdk6410 开发环境:Linux 突然想起一点,写这些驱动,内核需要配成支持抢占才行. 前面的博客已经将其它的基本知识都解释了,这里也就不过多的阐述了,咱就直接写代码吧 这次写的是adc ...

Jenkins Maven打包出错异常的解决方法

Jenkins是一个很好用的打包部署工具,实现一键式部署项目,在项目处于测试阶段或者对于运维人员来讲是非常方便的一个工具. 但是最近使用Jenkins部署项目时老是出错,主要是maven打包的问题,错 ...

CountDownLatch和CyclicBarrier 特点比较

详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp79   并发编程中的CountDownLatch和CyclicBarri ...

android中的五大布局(控件的容器,可以放button等控件)

一.android中五大布局相当于是容器,这些容器里可以放控件也可以放另一个容器,子控件和布局都需要制定属性. 1.相对布局:RelativeLayout @1控件默认堆叠排列,需要制定控件的相对位置 ...

在C#中对枚举进行位运算--枚举组合

由于枚举的基础类型类型为基本的数值类型,支持位运算,因此可以使用一个值表示多个枚举的组合,在定义枚举时需要指定枚举数为2的幂指数方便进行位运算,即枚举数为1,2,4,8…,或1,1<<1, ...


版权声明:本文为weixin_39608394原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。