我使用redis列表来做一个限制器,它大多数时候都按预期工作,但最近我发现有一些键没有过期时间。理想情况下,我将值“rpush”到列表中,并在一个中设置过期时间交易,并且在交易开始之前我也使用“watch”。
我本地环境没有复现这个bug,即使我使用jmeter批量请求相关api,比如1秒500个请求
预测:v2.1.2 PHP 7.4 Redis服务器5.0.10
$redisClient->watch($key);
$current = $redisClient->llen($key);
// Transaction start
$tx = $redisClient->transaction();
if ($current >= $limitNum) {
$redisClient->unwatch();
return false;
} else {
if ($redisClient->exists($key)) {
$tx->rpush($key, $now);
try {
$replies = $tx->execute();
return true;
} catch (\Exception $e) {
return false;
}
} else {
// Using transaction to let rpush and expire to be an atomic operation
$tx->rpush($key, $now);
$tx->expire($key, $expiryTime);
try {
$replies = $tx->execute();
return true;
} catch (\Exception $e) {
return false;
}
}
}
这是我的本地 Redis 服务器中的预期操作
Redis 事务是原子的。原子意味着要么处理所有命令,要么不处理任何命令。因此,在我的情况下,一把钥匙应该有有效期。
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号