以下应该在几个场景:
①多长时间内限制用户操作一次 使用命令:sadd expire
②多长时间内限制用户操作多少次 使用命令:ttl incr setex
$supply = isset($_POST['supply']) ? $_POST['supply'] : '';
//这个key记录三方标识
$key = "request_limit_".$supply;
//限制请求时间内
$time = 3;
//限制次数为100
$limit = 100;
//下面出现的问题是,key处于临界值时,进入if操作后,key过期,这时key incr将导致该key永远不会过期,可以在限制里加上判断
$check = $redis->exists($key);//用于检查key是否存在
if($check){
$count = $redis->incr($key);
if($count > $limit){
exit('您在{$time}秒内已经请求超过最大次 数,请稍后重试');
}
}else{
$redis->incr($key);
//限制时间为time秒
$redis->expire($key,$time);//设置key的过期时间可能下次key又进来了
}
//API业务逻辑
echo '<br/>';
...
对比改进,并发的作用
$supply = isset($_POST['supply']) ? $_POST['supply'] : '';
//这个key记录三方标识
$key = "request_limit_".$supply;
//限制请求时间内
$time = 3;
//限制次数为100
$limit = 100;
$check = $redis->ttl($key); //-1,未设置过期, -2 不存在 ; >1 超过1秒
if($check > 0){//0.1进来的,进来后过期又重新设置,成永久key,ttl判断为-1
$count = $redis->incr($key);
if($count > $limit){
exit('您在{$time}秒内已经请求超过最大次数,请稍后重试');
}
}else{
$redis->setex($key,$time,1);//过期重新设置该值
}
单个用户下单频率控制 利用sadd,当向集合中添加相同元素时返回0 设置控制时间 比如3秒内不能多次下单
判断ttl($key)时间 -2key不存在 -1未设置过期时间
$result = $this->_reConnect->sAdd($key, $uid);
if ($this->_reConnect->ttl($key) == -1) {
$this->_reConnect->expire($key, 3);
}
return $result;
下单总量控制 单位秒内总下单量不能超过一定范围
$key = Constant::TOTAL_USER_MAKE_ORDER;
$ttl = $this->_reConnect->ttl($key);
if ($ttl <= 0 || $ttl > 1 ) { //-1,未设置过期, -2 不存在 ; >1 超过1秒
$result = $this->_reConnect->setEx($key, 1, 1);
} else {
$result = $this->_reConnect->incr($key);
}
return (int)$result;
初次设置key的时候加上过期时间。
$rs = $this->_reConnect->incr($key);
if ($rs == 1) {
$exp = 86400 * 15;
$this->_reConnect->expire($key, $exp);
}