php超过半小时未付款自动删除订单,下单后半小时未付款订单自动取消的实现,延迟队列...

class RedisCli {

protected static $redis;

public static function getRedisInstance($conf){

if(isset(self::$redis)){

return self::$redis;

}

try{

$redis = new \Redis();

$re = $redis->connect($conf['host'], $conf['port']);

if(!$re){

throw new \Exception('connect redis error');

}

if(isset($conf['auth'])){

$re = $redis->auth($conf['auth']);

if(!$re){

throw new \Exception('redis auth error');

}

}

self::$redis = $redis;

return $redis;

}catch(\Exception $e){

throw new \Exception($e->getMessage());

}

}

public static function addOrder($redis, $key, $orderId){

$ttl = time() - 600;

$re = $redis->zadd($key, $ttl, $orderId);

return $re;

}

public static function getOrders($redis, $key, $num = 1){

/*

array(1) {

[3334]=>

float(1573703310)

}

*/

$orders = $redis->zrangebyscore($key, 0, time(), ['limit'=>[0, $num], 'withscores'=>TRUE]);

if(!$orders){

return [];

}

// 移除元素

foreach($orders as $k => $v){

$redis->zrem($key, $k);

}

return $orders;

}

public static function getAndDeleteOrder($redis, $key, $num = 1){

$script = " local score= redis.call(

'ZRANGEBYSCORE', KEYS[1], ARGV[1], ARGV[2], 'WITHSCORES' , 'LIMIT' , ARGV[3] , ARGV[4]

)

if score ~= false and #score ~= 0 then

local i = 1

while i <= #score do

redis.call('ZREM', KEYS[1] , score[i])

i=i+2

end

end

return score";

$result = $redis->eval($script, [$key, 0, time(), 0, $num], 1);

/*

$redis->eval的返回结果:

array(4) {

[0]=>

string(4) "3334"

[1]=>

string(10) "1573701647"

[2]=>

string(4) "3333"

[3]=>

string(10) "1573702072"

}

*/

$return = [];

$count = count($result);

if($count > 0){

for($i = 0; $i < $count; $i+=2){

$return[$result[$i]] = $result[$i + 1];

}

}

/*

array(1) {

[3334]=>

string(10) "1573702856"

}

*/

return $return;

}

}

$conf = ['host'=>'127.0.0.1', 'port'=>6379, 'auth'=>'123456'];

$redis = RedisCli::getRedisInstance($conf);

$key = 'orderkey';

$orderId = 3334;

// 添加

RedisCli::addOrder($redis, $key, $orderId);

// 消费,由于可能存在多进程的并发,使用Lua优化版,

while(true){

try{

// $data = RedisCli::getOrders($redis, $key);

$data = RedisCli::getAndDeleteOrder($redis, $key);

if(empty($data)){

sleep(1);

}else{

var_dump($data);

}

}catch(\Exception $e){

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值