<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/7/17
* Time: 9:27
*/
set_time_limit(0);
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$delayQueue = 'delay:queue';
$redis->zAdd($delayQueue, time() + 30,
json_encode(['id' => 11, 'content' => 'test test', 'email' => '998989@qq.com', 'name' => 'lww']));
echo "插入成功" . PHP_EOL;
//$redis->zAdd($delayQueue, time() + 120, json_encode(['id'=>2,'content' => 'test2 test2', 'email' => '998989@qq.com', 'name' => 'lww']));
//添加锁
function addLock($lockName, $timeout = 0)
{
global $redis;
//唯一标识
$identifier = uniqid();
//设置过期时间
$nowTime = time();
$endTime = $nowTime + $timeout;
while ($endTime >= $nowTime) {
if ($redis->setnx($lockName, $identifier)) {
return $identifier;
} else {
return false;
}
}
return false;
}
function releaseLock($lockName, $identifier)
{
global $redis;
while (true) {
// $redis->watch($lockName);
// var_dump($redis->get($lockName),$identifier );die;
if ($redis->get($lockName) == $identifier) {
//释放锁,即删除该key值
$redis->del($lockName);
return true;
} else {
//获取不到值说明,锁已经释放掉了,这时候不需要再监控这个锁值
//$redis->unwatch($lockName);
return false;
}
}
}
while (true) {
//获取有序集合里面的值,执行时间作为有序集合的分值
$firstDelayTask = $redis->zRange($delayQueue, 0, 0, true);
if (empty($firstDelayTask)) {
echo "没有可以执行的任务" . PHP_EOL;
sleep(1);
continue;
}
//获取任务值
$taskJson = key($firstDelayTask);
$delayTime = current($firstDelayTask);
$taskValue = json_decode($taskJson, true);
$nowTime = time();
if ($delayTime <= $nowTime) {
//小于或等于当前时间,说明要去执行该任务。为了保证一致性,所以选择加锁操作
$lock = 'id:' . $taskValue['id'];
if (!($identifier = addLock($lock))) {
echo "获取锁失败" . PHP_EOL;
//加锁失败,则从新执行
continue;
}
//加锁成功,将任务移动到执行队列里
$redis->multi();
//将任务从延迟队列移除
$redis->zRem($delayQueue, $taskJson);
//添加到执行队列里
$redis->rPush('execute:queue', $taskJson);
// 释放锁,执行完了开始释放锁
$redis->del($lock);
// return true;
$result = $redis->exec();
//判断事务是否成功
if (isset($result[0]) && $result[0] == 1) {
echo 'Successful task execution' . PHP_EOL;
} else {
$redis->discard();
echo "提交失败111" . PHP_EOL;
}
}
}
网友评论