Laravel10→11+Statamic4→5升级后AppServiceProvider启动停滞无异常排查
启动流程与服务初始化时机不匹配:Laravel 11 对应用启动流程做了精简调整,Schedule 实例的完全初始化时机晚于 Laravel 10;而 Statamic 5 的
AppServiceProvider仍在boot阶段直接尝试解析 Schedule 并注册任务,此时 Schedule 内部依赖的队列驱动、调度绑定等服务尚未完成初始化,触发了静默阻塞(而非抛出异常),直接中断后续服务提供者的启动流程。服务提供者加载顺序问题:
ylsideas/feature-flags包的服务提供者可能在 Statamic 的AppServiceProvider之后加载,因此在 Kernel 初始化阶段(Statamic 服务已启动但 feature-flags 的宏尚未注册),Event 门面的skipWithoutFeature宏还未就绪;Kernel 注册完成后所有服务提供者加载完毕,宏即可正常使用。任务类的静默阻塞:
HandleEntrySchedule任务的构造函数或内部初始化逻辑中,可能依赖了未就绪的服务,或触发了需要等待未初始化资源(如数据库连接、缓存服务)的操作,导致实例解析时陷入无限等待,无异常抛出但流程直接卡住。
逐行添加日志追踪:在 Statamic 的
AppServiceProvider中拆分调度代码并插入日志,精准定位卡住的步骤:use Illuminate\Support\Facades\Log; use Illuminate\Console\Scheduling\Schedule; use Statamic\Scheduling\HandleEntrySchedule; // ... Log::info('[Debug] 准备解析 Schedule 实例'); $schedule = $this->app->make(Schedule::class); Log::info('[Debug] 成功解析 Schedule 实例'); Log::info('[Debug] 准备创建 HandleEntrySchedule 实例'); $job = new HandleEntrySchedule(); Log::info('[Debug] 成功创建 HandleEntrySchedule 实例'); Log::info('[Debug] 准备注册调度任务'); $schedule->job($job)->everyMinute(); Log::info('[Debug] 成功注册调度任务');查看日志即可确定是解析 Schedule、实例化任务还是注册任务的步骤出现阻塞。
隔离测试任务类:临时注释调度注册代码,手动在路由闭包等晚启动的位置实例化
HandleEntrySchedule,检查是否能正常创建实例;也可逐步移除任务类构造函数的依赖,排查具体导致阻塞的依赖项。调整服务加载顺序:在 Laravel 11 的
bootstrap/providers.php中,将ylsideas/feature-flags的服务提供者手动放在 Statamic 服务提供者之前,验证宏是否能在 Kernel 阶段生效;同时可尝试将 Statamic 的调度代码移到booted方法(所有服务提供者启动完成后触发)中执行,看是否解决阻塞问题。启用底层错误追踪:
- 在
bootstrap/app.php开头添加:error_reporting(E_ALL); ini_set('display_errors', 1); ini_set('log_errors', 1); ini_set('error_log', storage_path('logs/debug_errors.log')); - 检查 PHP 错误日志(服务器
/var/log/php/目录或项目storage/logs下),可能存在未被 Laravel 捕获的底层致命错误,导致进程直接终止无 Laravel 日志输出。
- 在
断点调试:借助 Xdebug 工具,在调度代码的每一行设置断点,逐行执行并观察调用栈,定位到具体导致阻塞的方法或操作(如服务解析逻辑、数据库连接尝试等)。
内容的提问来源于stack exchange,提问作者Matthew Bradley

