针对日志并发问题,在自动存点中增加Redis分布式冷却锁,杜绝进程重复触发导致经验暴涨,完善单元测试

This commit is contained in:
pllx
2026-07-06 22:43:32 +08:00
parent a20bcf13be
commit 01a8e116a3
2 changed files with 43 additions and 1 deletions
+11 -1
View File
@@ -91,17 +91,27 @@ class AutoSaveExp extends Command
foreach ($roomMap as $roomId => $usernames) {
foreach ($usernames as $username) {
// 如果本轮已经处理过该用户,跳过发放经验(防止多房间/多开重复吃经验)
// 1. 如果本轮已经处理过该用户,跳过发放经验(防止多房间/多开重复吃经验)
if (isset($processedUsernames[$username])) {
continue;
}
// 2. 利用 Redis 缓存锁,防止在短时间内(200秒内)重复进行自动存点奖励(防御多进程并发/重复调度)
$cooldownKey = "user:auto_save_cooldown:{$username}";
if (Redis::exists($cooldownKey)) {
continue;
}
$user = $usersByUsername->get($username);
if (! $user) {
continue;
}
$this->processUser($user, $roomId, $expGainRaw, $jjbGainRaw, $superLevel);
// 3. 设置冷却标记,200秒后过期(本任务5分钟运行一次,200秒冷却期既防重复,又不影响下一次存点)
Redis::setex($cooldownKey, 200, 1);
$processedUsernames[$username] = true;
$totalProcessed++;
}