针对日志并发问题,在自动存点中增加Redis分布式冷却锁,杜绝进程重复触发导致经验暴涨,完善单元测试
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user