Laravel ResponseCache 源码解析:从请求到响应的完整缓存流程
Laravel ResponseCache 源码解析:从请求到响应的完整缓存流程
【免费下载链接】laravel-responsecacheSpeed up a Laravel app by caching the entire response项目地址: https://gitcode.com/gh_mirrors/la/laravel-responsecache
Laravel ResponseCache 是一个强大的 Laravel 扩展包,它通过缓存整个响应来显著提升 Laravel 应用的性能。本文将深入解析其内部工作原理,带你了解从请求到响应的完整缓存流程。
1. 请求拦截:CacheResponse 中间件的作用
整个缓存流程的入口是src/Middlewares/CacheResponse.php中间件。当请求进入应用时,该中间件会首先检查是否启用了缓存以及是否应该绕过缓存。
// src/Middlewares/CacheResponse.php if ($this->responseCache->enabled($request) && ! $this->responseCache->shouldBypass($request)) { // 尝试获取缓存响应 }中间件会先检查请求是否已经被缓存,如果有缓存则直接返回缓存的响应,从而跳过后续的业务逻辑处理,极大提升响应速度。
2. 缓存决策:CacheProfile 的关键作用
缓存系统如何决定哪些请求应该被缓存?这是由CacheProfile接口及其实现类负责的。默认实现是CacheAllSuccessfulGetRequests。
// src/CacheProfiles/CacheAllSuccessfulGetRequests.php public function shouldCacheRequest(Request $request): bool { if ($request->ajax()) { return false; } if ($this->isRunningInConsole()) { return false; } return $request->isMethod('get'); }这个方法决定了只有非 AJAX、非控制台且使用 GET 方法的请求才会被考虑缓存。
3. 响应判断:哪些响应可以被缓存
除了请求需要满足条件外,响应也需要通过缓存判断。shouldCacheResponse方法检查响应状态码和内容类型:
// src/CacheProfiles/CacheAllSuccessfulGetRequests.php public function shouldCacheResponse(Response $response): bool { if (! $this->hasCacheableResponseCode($response)) { return false; } if (! $this->hasCacheableContentType($response)) { return false; } return true; }默认配置下,只有成功状态码(2xx)和重定向状态码(3xx),且内容类型为文本或 JSON 的响应才会被缓存。
4. 缓存存储:响应的序列化与存储
当确定要缓存响应时,系统会对响应进行一些处理后再存储:
// src/Middlewares/CacheResponse.php protected function makeReplacementsAndCacheResponse( Request $request, Response $response, ?int $lifetimeInSeconds = null, array $tags = [] ): void { $cachedResponse = clone $response; $this->getReplacers()->each(fn (Replacer $replacer) => $replacer->prepareResponseToCache($cachedResponse)); $this->responseCache->cacheResponse($request, $cachedResponse, $lifetimeInSeconds, $tags); }这里会先克隆响应对象,然后应用各种替换器(Replacer)处理响应内容,最后调用cacheResponse方法将响应存储起来。
5. 缓存替换器:动态内容的处理
替换器(Replacer)是处理响应中动态内容的关键组件。例如,CsrfTokenReplacer可以处理 CSRF 令牌这类需要动态生成的内容。
替换器配置在config/responsecache.php文件中,系统会自动加载并应用这些替换器:
// src/Middlewares/CacheResponse.php protected function getReplacers(): Collection { return collect(config('responsecache.replacers')) ->map(fn (string $replacerClass) => app($replacerClass)); }6. 缓存命中:从缓存中读取响应
当后续相同请求进来时,系统会直接从缓存中读取响应:
// src/Middlewares/CacheResponse.php protected function getCachedResponse(Request $request, array $tags = []): false|Response { try { $response = $this->responseCache->getCachedResponseFor($request, $tags); } catch (CouldNotUnserialize $exception) { throw $exception; } catch (Throwable $exception) { report("Unable to retrieve cached response when one was expected. Error: {$exception->getMessage()}"); return false; } event(new ResponseCacheHit($request)); $response = $this->addCacheAgeHeader($response); $this->getReplacers()->each(function (Replacer $replacer) use ($response) { $replacer->replaceInCachedResponse($response); }); return $response; }读取缓存后,系统还会再次应用替换器,确保动态内容被正确替换,然后返回缓存的响应。
7. 缓存管理:缓存的清除与失效
Laravel ResponseCache 提供了清除缓存的命令:ClearCommand,位于src/Commands/ClearCommand.php。你可以通过 Artisan 命令手动清除缓存,也可以在配置文件中设置缓存的过期时间。
总结
Laravel ResponseCache 通过优雅的中间件设计和灵活的缓存策略,为 Laravel 应用提供了简单而强大的响应缓存解决方案。它的工作流程可以概括为:
- 请求进入,CacheResponse 中间件拦截
- 判断是否启用缓存及请求是否可缓存
- 如果缓存命中,则返回缓存响应
- 如果缓存未命中,继续处理请求
- 判断响应是否可缓存
- 处理响应并存储到缓存
- 返回响应
通过这个流程,Laravel ResponseCache 能够显著减少服务器处理时间,提高应用响应速度,为用户提供更好的体验。
【免费下载链接】laravel-responsecacheSpeed up a Laravel app by caching the entire response项目地址: https://gitcode.com/gh_mirrors/la/laravel-responsecache
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
