diff --git a/extend/catcher/library/rate/GrantLimit.php b/extend/catcher/library/rate/GrantLimit.php index fa9d783..151892f 100644 --- a/extend/catcher/library/rate/GrantLimit.php +++ b/extend/catcher/library/rate/GrantLimit.php @@ -7,4 +7,80 @@ // | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt ) // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] -// +---------------------------------------------------------------------- \ No newline at end of file +// +---------------------------------------------------------------------- +namespace catcher\library\rate; +use catcher\exceptions\FailedException; + +/** + * 固定窗口限流 + * + * Class GrantLimit + * @package catcher\library\rate + */ +class GrantLimit +{ + use Redis; + + protected $ttl = 60; + + protected $limit = 1000; + + protected $key; + + public function __construct($key) + { + $this->key = $key; + + $this->init(); + } + + /** + * 是否到达限流 + * + * @time 2020年06月30日 + * @return void + */ + public function overflow() + { + if ($this->getCurrentVisitTimes() > $this->limit) { + throw new FailedException('访问限制'); + } + + $this->inc(); + } + + /** + * 增加接口次数 + * + * @time 2020年06月30日 + * @return void + */ + public function inc() + { + $this->getRedis()->incr($this->key); + } + + /** + * 初始化 + * + * @time 2020年06月30日 + * @return void + */ + protected function init() + { + if (!$this->getRedis()->exists($this->key)) { + $this->getRedis()->setex($this->key, $this->ttl, 0); + } + } + + /** + * 获取当前访问次数 + * + * @time 2020年06月30日 + * @return mixed + */ + protected function getCurrentVisitTimes() + { + return $this->getRedis()->get($this->key); + } +} \ No newline at end of file diff --git a/extend/catcher/library/rate/Redis.php b/extend/catcher/library/rate/Redis.php index 0aa15e2..09268b1 100644 --- a/extend/catcher/library/rate/Redis.php +++ b/extend/catcher/library/rate/Redis.php @@ -8,29 +8,48 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- -namespace catcher\library; +namespace catcher\library\rate; use think\facade\Cache; -class Redis +trait Redis { - protected $handle = null; + protected $redis = null; - - public function __construct() + protected function getRedis() { - if (!$this->handle) { - $this->handle = Cache::store('redis')->handler(); + if (!$this->redis) { + $this->redis = Cache::store('redis')->handler(); } - return $this->handle; + return $this->redis; } - - - public function __call($name, $arguments) + /** + * 设置 ttl + * + * @time 2020年06月30日 + * @param $ttl + * @return $this + */ + public function ttl($ttl) { - // TODO: Implement __call() method. - return $this->handle->{$name}(...$arguments); + $this->ttl = $ttl; + + return $this; + } + + /** + * 设置限制次数 + * + * @time 2020年06月30日 + * @param $limit + * @return $this + */ + public function limit($limit) + { + $this->limit = $limit; + + return $this; } } \ No newline at end of file