Laravel Sanctum与Octane搭配超时问题:数据库断开方案的疑问与优化
为什么启用DisconnectFromDatabases能解决超时?
Octane基于常驻进程运行,默认会复用数据库连接以提升性能。但Supabase托管的Postgres会主动断开长时间闲置的连接,而Octane进程无法感知连接已被远端关闭,后续请求尝试使用这个无效连接时,就会因等待响应超时触发408错误。
启用DisconnectFromDatabases后,每个请求结束都会强制断开数据库连接,下次请求重新建立新连接,彻底避免了使用无效连接的情况,但频繁创建/销毁连接会直接拉低性能。
无需牺牲性能的替代方案
1. 配置数据库连接心跳,保持连接活跃
在config/database.php的Postgres连接配置中添加TCP心跳参数,让客户端主动维持连接,防止Supabase端断开闲置连接:
'pgsql' => [ 'driver' => 'pgsql', 'url' => env('DATABASE_URL'), // ... 其他默认配置 'options' => extension_loaded('pdo_pgsql') ? array_filter([ PDO::PGSQL_ATTR_KEEPALIVES => 1, PDO::PGSQL_ATTR_KEEPALIVES_IDLE => 30, // 闲置30秒后发送心跳 PDO::PGSQL_ATTR_KEEPALIVES_INTERVAL => 10, // 每10秒发送一次心跳 PDO::PGSQL_ATTR_KEEPALIVES_COUNT => 5, // 连续5次心跳无响应则断开 PDO::PGSQL_ATTR_DISABLE_PREPARES => true, // 禁用预编译语句,避免连接复用冲突 ]) : [], ],
2. 仅在连接失效时回收连接
保留Octane默认的连接复用机制,监听数据库连接失败事件,仅当连接确实被远端断开时才主动回收,兼顾性能和稳定性:
在App\Providers\AppServiceProvider的boot方法中添加:
use Illuminate\Database\Events\ConnectionFailed; use Illuminate\Support\Facades\Event; use Laravel\Octane\Facades\Octane; Event::listen(ConnectionFailed::class, function (ConnectionFailed $event) { // 匹配Supabase连接断开的错误信息 if (str_contains($event->exception->getMessage(), 'closed the connection') || str_contains($event->exception->getMessage(), 'no connection to the server')) { Octane::disconnectDatabase($event->connectionName); } });
3. 优化请求内数据库操作规范
- 确保每个请求结束后,所有数据库事务都已提交或回滚,避免连接长时间处于挂起状态
- 避免在请求外(如Octane启动时)执行持久化数据库操作,防止连接被长期占用
关于Sanctum Cookie认证的兼容性
Sanctum基于Cookie的会话认证与Octane完全兼容,Octane默认的FlushTemporaryContainerInstances处理器会在每个请求结束后清空请求、会话等临时实例,保证会话数据在请求间隔离,无需额外适配。此次超时问题核心是数据库连接复用与Supabase端闲置断开机制的冲突,和Sanctum本身无关。
内容的提问来源于stack exchange,提问作者Strikr
相关产品推荐
相关产品推荐

