分享个自己封装的限流trait
<?php namespace App\Traits; use App\Exceptions\BusinessException; use Illuminate\Support\Facades\Redis; trait RedisLimiter { /** * 限流 * @param $key * @param $limit * @param $expire_time * @return bool * @throws BusinessException * @author wzx 2023/4/25 17:35 */ public static function set($key, $limit, $expire_time) { $current_time = time(); $result = Redis::eval(self::lua(), 1, $key, $limit, $expire_time, $current_time); if ($result == 0) { throw new BusinessException([-1, '请求频繁']); } return true; } private static function lua(): string { return <<<LUA local key = KEYS[1] local limit = tonumber(ARGV[1]) local expire_time = tonumber(ARGV[2]) local current_time = tonumber(ARGV[3]) local count = redis.call('get', key) if count and tonumber(count) >= limit then return 0 else redis.call('incr', key) redis.call('expire', key, expire_time) return 1 end LUA; } } 使用
$key = "user:xxx" . $user_id; // 一分钟请求1次 RedisLimiter::set($key, 1, 60); 本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
高认可度评论:
不错,laravel已经内置了
不错,laravel已经内置了
这是固定时间窗口吧?
没玩过Lua,用redis调Lua再调redis ,跟直接用redis有什么区别。
不是原生就有 ThrottleRequestsWithRedis
Illuminate\Redis\Limiters\DurationLimiter
没怎么用过,跟原生的有哪些不一样
疑问:
在应用层限流有瓶颈,流量上来,会直接把服务打挂了,建议在网关层限流,推荐 apisix。