调整
This commit is contained in:
@@ -212,39 +212,55 @@ class QueueJob
|
||||
*/
|
||||
public function acquireLock($sRedisKey, $sRedisValue, $job)
|
||||
{
|
||||
$isLocked = $this->QueueRedis->startJob($sRedisKey, $sRedisValue, $this->lockExpire);
|
||||
|
||||
if (!$isLocked) {
|
||||
$currentLockValue = $this->QueueRedis->getRedisValue($sRedisKey); // 获取当前锁值
|
||||
$jobStatus = $this->QueueRedis->getJobStatus($sRedisKey);
|
||||
|
||||
// 若锁值为空或过期,强制抢占锁
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 1. 前置校验:先检查是否已完成/失败(优先于锁操作)
|
||||
$jobStatus = $this->QueueRedis->getJobStatus($sRedisKey);
|
||||
if (in_array($jobStatus, ['completed', 'failed'])) {
|
||||
$this->log("任务已终止,删除任务 | 键: {$sRedisKey} | 状态: {$jobStatus}");
|
||||
$job->delete();
|
||||
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