Laravel API throttle 原理分析

1,292次阅读
没有评论

Laravel 自从 5.2 版本起就加入了 throttle 中间件来进行限流。下面我们看一下具体的原理是怎样实现的。

ThrottleRequests
throttle 中间件的 class 为 Illuminate\Routing\Middleware\ThrottleRequests。代码如下:

class ThrottleRequests
{

 /**
 * The rate limiter instance.
 *
 * @var \Illuminate\Cache\RateLimiter
 */
protected $limiter;

/**
 * Create a new request throttler.
 *
 * @param  \Illuminate\Cache\RateLimiter  $limiter
 * @return void
 */
public function __construct(RateLimiter $limiter)
{
    $this->limiter = $limiter;
}

 ...

}
在构造函数中初始化了一个 RateLimiter 类,代码如下:

class RateLimiter
{
protected $cache;

public function __construct(Cache $cache)
{
    $this->cache = $cache;
}

}
这表示处理限流的相关信息存储位置与我们在项目中配置的 cache driver 一致。接着回到 ThrottleRequests 中。

// ThrottleRequests
public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
{
$key = $this->resolveRequestSignature($request);

$maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts);

if ($this->limiter->tooManyAttempts($key, $maxAttempts, $decayMinutes)) {
    throw $this->buildException($key, $maxAttempts);
}

$this->limiter->hit($key, $decayMinutes);

$response = $next($request);

return $this->addHeaders(
    $response, $maxAttempts,
    $this->calculateRemainingAttempts($key, $maxAttempts)
);

}

protected function resolveRequestSignature($request)
{
if ($user = $request->user()) {
return sha1($user->getAuthIdentifier());
}

if ($route = $request->route()) {
    return sha1($route->getDomain().'|'.$request->ip());
}

throw new RuntimeException(
    'Unable to generate the request signature. Route unavailable.'
);

}

// RateLimiter
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
{
if ($this->attempts($key) >= $maxAttempts) {
if ($this->cache->has($key.’:timer’)) {
return true;
}

    $this->resetAttempts($key);
}

return false;

}

public function hit($key, $decayMinutes = 1)
{
$this->cache->add(
$key.’:timer’, $this->availableAt($decayMinutes * 60), $decayMinutes
);

$added = $this->cache->add($key, 0, $decayMinutes);

$hits = (int) $this->cache->increment($key);

if (! $added && $hits == 1) {
    $this->cache->put($key, 1, $decayMinutes);
}

return $hits;

}
和我们熟知的中间件一样,throttle 也通过 handle 方法来进行处理。其中 key 返回的是一个用户标记或者 ip 标记。即如果用户已经登录,那么根据用户来判断限流,否则根据 IP 进行限流。接着判断是否达到了限流的上限,如果达到上限抛出异常。否则针对指定的 key 将访问次数加 1. 然后在响应中加入指定的 HEADER 后返回。至此,中间件流程基本结束。

HEADERS
在加入限流中间件之后,会在 API 中加入特定的 HEADER,例如我们设置某个路由的中间件如下:

$api->get(‘demo’, ‘xxxxController@xx’)->middleware(‘throttle:5,1’);
这表示 demo 这个 API 每个用户每 1 分钟只能访问 5 次。那么在我们访问的时候会看到在响应中加入了 2 个新的 HEADER。

X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
表示路由的 API 限制次数为 5 次,还可以访问 4 次。当我们达到访问上限之后再次访问 API,就会得到如下的 HEADER:

X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
Retry-After: 43
X-RateLimit-Reset: 1555506730
新增加的两个 HEADER 中,Retry-After 表示我们可以在 43 秒后重新访问,限流的限制将在 X-RateLimit-Reset 返回的时间戳进行重置。

EXTRA
其实 Laravel 还为我们提供了 ThrottleRequestsWithRedis 类,所实现的功能与前面一致,只不过使用了 Redis 来进行数据存储。

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2023 年 12 月
 123
45678910
11121314151617
18192021222324
25262728293031
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026 Jay 2025-12-22 09...
面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25 鹭羽 2025-12-13 22:37...
钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议 梦晨 2025-12-11 15:33:51 来源:量子位 A...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1 十三 2025-12-15 14:13:14 ...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了 衡宇 2025-12-10 12:3...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案 十三 2025-12-10 1...
九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局 量子位的朋友们 2025-12-10 18:...
乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头 梦瑶 2025-12-10 20:41:15 来源:量子位 梦瑶 发自 ...