Laravel中如何实现按天限流而非按分钟限流?
Laravel 替换按分钟限流为按天限流的实现方案
嗨,要把现有的按分钟限流改成按天其实很简单,Laravel自带的RateLimiter已经支持自定义限流周期,咱们直接调整代码逻辑就行,我给你分两种常用场景说明:
基础方案:滑动窗口24小时限流
这种方案是从用户第一次请求开始计算,往后24小时内限制请求次数(比如24小时内最多发5条消息),对应你原来的代码,只需要在hit方法里指定过期时间为1440分钟(24*60)即可:
use Illuminate\Support\Facades\RateLimiter; // 定义每天允许的请求次数 $perDay = 5; $limiterKey = 'send-message:' . $user->id; if (RateLimiter::remaining($limiterKey, $perDay)) { // 指定限流周期为1440分钟(24小时) RateLimiter::hit($limiterKey, 1440); // 这里写发送消息的业务逻辑... } else { // 超过限流次数后的处理,比如返回提示 // return response()->json(['msg' => '24小时内发送消息次数已达上限,请稍后再试'], 429); }
为什么这样改?原来的RateLimiter::hit()默认是1分钟后过期(对应按分钟限流的周期),现在我们手动传入1440,就把周期拉长到了24小时,完美替换原来的按分钟逻辑。
进阶方案:自然天(0点自动重置)限流
如果你的需求是按自然天计算(比如每天0点自动重置次数,而不是从第一次请求算24小时),那我们可以把当前日期加入限流的key中,让每天的限流独立计数:
use Illuminate\Support\Facades\RateLimiter; use Carbon\Carbon; $perDay = 5; // 把当前日期拼入key,确保每天的限流key唯一 $limiterKey = 'send-message:' . $user->id . ':' . Carbon::today()->format('Y-m-d'); if (RateLimiter::remaining($limiterKey, $perDay)) { // 可以设置过期时间为当天剩余的分钟数,避免缓存浪费 $expireMinutes = Carbon::today()->endOfDay()->diffInMinutes(); RateLimiter::hit($limiterKey, $expireMinutes); // 发送消息的业务逻辑... } else { // 处理超限逻辑,比如提示"今日发送次数已达上限,请明天再试" }
这个方案的好处是,到了每天0点,Carbon::today()->format('Y-m-d')会自动更新,生成新的限流key,旧的key会在当天结束后自动过期,无需手动清理缓存。
内容的提问来源于stack exchange,提问作者Axel
相关产品推荐
相关产品推荐

