调整
This commit is contained in:
@@ -212,39 +212,55 @@ class QueueJob
|
|||||||
*/
|
*/
|
||||||
public function acquireLock($sRedisKey, $sRedisValue, $job)
|
public function acquireLock($sRedisKey, $sRedisValue, $job)
|
||||||
{
|
{
|
||||||
$isLocked = $this->QueueRedis->startJob($sRedisKey, $sRedisValue, $this->lockExpire);
|
// 1. 前置校验:先检查是否已完成/失败(优先于锁操作)
|
||||||
|
$jobStatus = $this->QueueRedis->getJobStatus($sRedisKey);
|
||||||
if (!$isLocked) {
|
if (in_array($jobStatus, ['completed', 'failed'])) {
|
||||||
$currentLockValue = $this->QueueRedis->getRedisValue($sRedisKey); // 获取当前锁值
|
$this->log("任务已终止,删除任务 | 键: {$sRedisKey} | 状态: {$jobStatus}");
|
||||||
$jobStatus = $this->QueueRedis->getJobStatus($sRedisKey);
|
$job->delete();
|
||||||
|
|
||||||
// 若锁值为空或过期,强制抢占锁
|
|
||||||
if (empty($currentLockValue) || $jobStatus === false) {
|
|
||||||
$this->log("数据为空 | 状态: {$currentLockValue} | 键: {$jobStatus}");
|
|
||||||
$isLocked = $this->QueueRedis->startJob($sRedisKey, $sRedisValue, $this->lockExpire);
|
|
||||||
if ($isLocked) return true;
|
|
||||||
}
|
|
||||||
if (in_array($jobStatus, ['completed', 'failed'])) {
|
|
||||||
$this->log("任务已完成或失败,删除任务 | 状态: {$jobStatus} | 键: {$sRedisKey}");
|
|
||||||
$job->delete();
|
|
||||||
} else {
|
|
||||||
$attempts = $job->attempts();
|
|
||||||
if ($attempts >= $this->maxRetries) {
|
|
||||||
$this->log("超过最大重试次数({$this->maxRetries}),停止重试 | 键: {$sRedisKey}");
|
|
||||||
$job->delete();
|
|
||||||
} else {
|
|
||||||
$lockTtl = $this->QueueRedis->getLockTtl($sRedisKey);
|
|
||||||
$delay = $lockTtl > 0 ? $lockTtl + 5 : 30;
|
|
||||||
// 限制最大延迟时间
|
|
||||||
$delay = min($delay, $this->maxDelay);
|
|
||||||
$this->log("锁竞争,{$delay}秒后重试({$attempts}/{$this->maxRetries}) | 键: {$sRedisKey}");
|
|
||||||
$job->release($delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->log("写入成功 | 状态: {$sRedisKey} | 键: {$sRedisValue}");
|
|
||||||
return true;
|
// 2. 尝试获取锁
|
||||||
|
$isLocked = $this->QueueRedis->startJob($sRedisKey, $sRedisValue, $this->lockExpire);
|
||||||
|
if ($isLocked) {
|
||||||
|
$this->log("成功获取锁 | 键: {$sRedisKey} | 锁值: {$sRedisValue}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 锁竞争处理:二次校验状态+超时抢占
|
||||||
|
$currentLockValue = $this->QueueRedis->getRedisValue($sRedisKey);
|
||||||
|
$jobStatus = $this->QueueRedis->getJobStatus($sRedisKey);
|
||||||
|
|
||||||
|
// 3.1 若状态已终止,直接删除任务
|
||||||
|
if (in_array($jobStatus, ['completed', 'failed'])) {
|
||||||
|
$this->log("任务已终止,删除任务 | 键: {$sRedisKey} | 状态: {$jobStatus}");
|
||||||
|
$job->delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.2 锁已过期(值为空或TTL<=0),强制抢占
|
||||||
|
$lockTtl = $this->QueueRedis->getLockTtl($sRedisKey);
|
||||||
|
if (empty($currentLockValue) || $lockTtl <= 0) {
|
||||||
|
$this->log("锁已过期,强制抢占 | 键: {$sRedisKey} | TTL: {$lockTtl}");
|
||||||
|
$isLocked = $this->QueueRedis->startJob($sRedisKey, $sRedisValue, $this->lockExpire);
|
||||||
|
if ($isLocked) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.3 未获取到锁,按重试策略处理
|
||||||
|
$attempts = $job->attempts();
|
||||||
|
if ($attempts >= $this->maxRetries) {
|
||||||
|
$this->log("超过最大重试次数({$this->maxRetries}),删除任务 | 键: {$sRedisKey}");
|
||||||
|
$job->delete();
|
||||||
|
} else {
|
||||||
|
// 动态计算延迟时间(基于当前锁剩余时间)
|
||||||
|
$delay = $lockTtl > 0 ? $lockTtl + 5 : 30;
|
||||||
|
$delay = min($delay, $this->maxDelay);
|
||||||
|
$this->log("锁竞争,延迟{$delay}秒重试({$attempts}/{$this->maxRetries}) | 键: {$sRedisKey}");
|
||||||
|
$job->release($delay);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user