直接贴代码
<?php
namespace App\Cache\Redis\CommonResolve\Utils;
use App\Cache\Redis\CommonResolve\BaseResolve;
use Illuminate\Support\Carbon;
/**
* 计数器类
* Class Counter
* @package App\Cache\Redis\CommonResolve\Utils
*/
class Counter
{
/**
* @var int
*/
public $expireTime = 3600;
public $key = '';
/**
* @var int
*/
public $limit = 10;
/**
* @var string
*/
public $drive = 'redis';
/**
* @var string
*/
public $timestamp = '';
/**
* @var string
*/
public $startTimestamp = '';
/**
* @var string
*/
public $endTimestamp = '';
/**
* @return string
*/
public function getStartTimestamp(): string
{
return $this->startTimestamp;
}
/**
* @param string $startTimestamp
*/
public function setStartTimestamp(string $startTimestamp): void
{
$this->startTimestamp = $startTimestamp;
}
/**
* @return string
*/
public function getEndTimestamp(): string
{
return $this->endTimestamp;
}
/**
* @param string $endTimestamp
*/
public function setEndTimestamp(string $endTimestamp): void
{
$this->endTimestamp = $endTimestamp;
}
/**
* @return string
*/
public function getTimestamp(): string
{
return $this->timestamp ? $this->timestamp : Carbon::now()->timestamp;
}
/**
* @param string $timestamp
*/
public function setTimestamp(string $timestamp): void
{
$this->timestamp = $timestamp;
}
/**
* @return string
*/
public function getKey(): string
{
return $this->key;
}
/**
* @param string $key
*/
public function setKey(string $key): void
{
$this->key = $key;
}
/**
* @return int
*/
public function getExpireTime(): int
{
return $this->expireTime;
}
/**
* @return int
*/
public function getLimit(): int
{
return $this->limit;
}
/**
* @param int $limit
*/
public function setLimit(int $limit): void
{
$this->limit = $limit;
}
/**
* @param int $expireTime
*/
public function setExpireTime(int $expireTime): void
{
$this->expireTime = $expireTime;
}
/**
* @return string
*/
public function getDrive(): string
{
return $this->drive;
}
/**
* @param string $drive
*/
public function setDrive(string $drive): void
{
$this->drive = $drive;
}
/**
* @return array
* @throws \Exception
*/
public function counter()
{
$sha = CustomRedis::script('load', 'counter.lua');
list($bool, $count) = CustomRedis::evalSha($sha, 1,
$this->getKey(),
$this->getLimit(),
$this->getExpireTime(),
$this->getTimestamp(),
$this->getStartTimestamp(),
$this->getEndTimestamp()
);
return [$bool, $count];
}
}
couter.lua
local visitTimes = redis.call('incr', KEYS[1])
local logVisitKey = KEYS[1] .. ':log:visit';
if (visitTimes == 1) then
redis.call('expire', KEYS[1], tonumber(ARGV[2]));
redis.call('expire', logVisitKey, tonumber(ARGV[2]));
end
redis.call('zadd', logVisitKey,ARGV[3],visitTimes);
local logVisitCount = redis.call('zcard', logVisitKey);
if ARGV[4] and ARGV[5] then
local logVisitRangeCount = redis.call('zcount',logVisitKey,ARGV[4],ARGV[5])
logVisitCount = logVisitRangeCount;
end
if logVisitCount > tonumber(ARGV[1]) then
return {0,logVisitCount}
else
return {1,logVisitCount}
end