Laravel 9/10内存占用激增(疑因Sanctum)如何优化?
一、为何未使用Sanctum的路由也会大幅增加内存占用?
Laravel的服务提供者是全局启动阶段加载的,Sanctum的SanctumServiceProvider默认会注册到应用的服务提供者列表中。不管你的路由是否使用Sanctum中间件,框架启动时都会执行该服务提供者的register和boot方法:
- 注册Sanctum相关的服务绑定(如Guard、令牌模型等)
- 全局注册Sanctum的中间件(即使路由没引用,中间件类已被加载到内存)
- 初始化认证驱动、令牌验证逻辑等基础组件
这些操作会加载大量Sanctum相关的类和配置,直接导致应用启动时的内存占用上升,和路由是否实际使用Sanctum无关。
另外,Laravel 9/10本身的基础内存占用比Laravel 8高,因为PHP 8.x的内核特性、Laravel框架新增的内置功能(如更完善的类型提示、新增组件)都会带来一定的内存开销,再叠加Sanctum的加载,差距会更明显。
二、如何优化降低内存占用?
1. 针对Sanctum的优化
延迟加载Sanctum服务提供者:
打开config/app.php,将Laravel\Sanctum\SanctumServiceProvider::class从providers数组移到deferred_providers数组中。这样Sanctum的服务只会在实际用到相关功能(如访问需要Sanctum认证的路由)时才会加载,能大幅降低未使用Sanctum的路由的内存占用。注意:如果Jetstream依赖Sanctum的全局服务,可能需要测试兼容性,部分场景下可能需要调整Jetstream的初始化逻辑。禁用Sanctum不必要的功能:
在config/sanctum.php中,关闭不需要的配置,比如:// 禁用SPA认证(如果只做API接口) 'stateful' => [], // 关闭令牌过期检查(如果不需要) 'expiration' => null,
2. 优化Jetstream的开销
Jetstream本身会加载大量组件(如团队管理、邮箱验证、会话管理),如果你的应用用不到这些功能,可以在config/jetstream.php中禁用:
'features' => [ // Features::termsAndPrivacyPolicy(), // Features::profilePhotos(), // Features::api(), // 如果不需要Jetstream的API支持,可关闭 // Features::teams(), ],
减少Jetstream加载的组件数量,能直接降低内存占用。
3. 利用Octane优化长期内存开销
你已经在使用Octane,它的常驻进程模式能大幅降低重复请求的内存开销:
- Octane会在进程启动时一次性加载所有框架类和服务,后续请求复用该进程,避免每次请求重新加载类
- 确保配置Octane清理请求级别的状态,比如在
config/octane.php中开启flush_app_after_request,避免内存泄漏
长期运行后,Octane进程的内存会稳定在一个合理值,不会每次请求都出现大幅波动。
4. 调整PHP与框架基础配置
- 优化OPcache配置:
确保PHP的OPcache已开启并配置合理,缓存框架和应用的类文件,减少每次请求的类加载开销。示例配置:opcache.enable=1 opcache.memory_consumption=256 opcache.max_accelerated_files=10000 opcache.validate_timestamps=0 - 精简全局中间件:
打开app/Http/Kernel.php,移除全局中间件中不需要的项(比如你的API应用不需要Session、Cookie中间件的话,可从$middleware数组中移除)。
5. 换回JWT的可行性与操作步骤
如果一定要换回tymondesigns/jwt-auth,确实需要调整Jetstream的配置,步骤如下:
- 卸载Sanctum:
composer remove laravel/sanctum - 安装并配置tymondesigns/jwt-auth:
composer require tymon/jwt-auth,执行发布配置、生成密钥等步骤 - 修改Jetstream的认证驱动:在
config/jetstream.php中,将guard改为JWT的Guard(比如api),并调整Jetstream的控制器逻辑,替换Sanctum的认证代码为JWT验证 - 更新路由中间件:将API路由中的
auth:sanctum替换为auth:api(需确保JWT的Guard已配置)
这个过程有一定复杂度,需要逐部分替换Jetstream与Sanctum绑定的逻辑,适合对Laravel和Jetstream源码有一定了解的开发者。
内容的提问来源于stack exchange,提问作者SymmetricsWeb

