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

编程

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

延迟队列的应用场景:

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

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

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

<?php

classDelayQueue

{

protected$prefix="delay_queue:";

protected$redis=null;

protected$key="";

publicfunction__construct($queue,$config=[])

{

$this->key=$this->prefix.$queue;

$this->redis=newRedis();

$this->redis->connect($config["host"],$config["port"],$config["timeout"]);

$this->redis->auth($config["auth"]);

}

publicfunctiondelTask($value)

{

return$this->redis->zRem($this->key,$value);

}

publicfunctiongetTask()

{

//获取任务,以0和当前时间为区间,返回一条记录

return$this->redis->zRangeByScore($this->key,0,time(),["limit"=>[0,1]]);

}

publicfunctionaddTask($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)

);

}

publicfunctionrun()

{

//每次只取一条任务

$task=$this->getTask();

if(empty($task)){

returnfalse;

}

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

returntrue;

}

returnfalse;

}

}

$dq=newDelayQueue("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=newDelayQueue("close_order",[

"host"=>"127.0.0.1",

"port"=>6379,

"auth"=>"",

"timeout"=>60,

]);

while(true){

$dq->run();

usleep(100000);

}

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要请戳这里

以上是 php使用redis的有序集合zset实现延迟队列 的全部内容, 来源链接: utcz.com/z/514601.html

回到顶部