You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 19:57:48