
Laravel 开发环境下使用 php artisan serve 执行长时间 Shell 命令(如 FFmpeg 视频处理)会阻塞整个 PHP 内置服务器,导致其他请求无法响应;根本原因在于该服务器为单线程、无并发能力,而非 Session 锁定问题。
laravel 开发环境下使用 `php artisan serve` 执行长时间 shell 命令(如 ffmpeg 视频处理)会阻塞整个 php 内置服务器,导致其他请求无法响应;根本原因在于该服务器为单线程、无并发能力,而非 session 锁定问题。
在构建 Laravel 视频编辑应用时,常见做法是通过 AJAX 触发后端执行耗时的 shell_exec('ffmpeg ...') 命令。虽然逻辑上可通过异步方式(如 nohup + 进程后台化)确保任务不随浏览器关闭而中断,并配合轮询或 WebSocket 通知前端完成状态,但开发者常遇到一个隐蔽却关键的问题:所有其他页面(如 http://localhost:8000/dashboard 或 /settings)在 FFmpeg 运行期间完全无法加载——表现为请求挂起、超时或白屏。
⚠️ 注意:这不是典型的「Session 阻塞」问题(即多个请求因共享同一 session 文件而串行化)。尽管 session_write_close() 或 $request->session()->save() 在某些场景下可缓解阻塞,但在 php artisan serve 环境中,它根本不起作用——因为该内置服务器本质上是单进程、单线程的 CLI Web 服务器,任何阻塞式 PHP 脚本(无论是否操作 Session)都会让整个服务器停摆。
✅ 正确解法是脱离开发服务器,迁移到生产级 Web 服务器环境:
推荐方案:使用 Apache 或 Nginx + PHP-FPM
将项目部署到本地 Apache(如 XAMPP/MAMP)或配置 Nginx + PHP-FPM。此时每个 HTTP 请求由独立的 PHP Worker 进程处理,FFmpeg 子进程在后台运行不会影响其他请求的响应能力。-
验证示例(Apache 环境下):
// routes/web.php Route::post('/process-video', function (Request $request) { $input = storage_path('app/videos/input.mp4'); $output = storage_path('app/videos/output.mp4'); // 后台执行,不阻塞主线程 $command = "ffmpeg -i {$input} -c:v libx264 -preset fast {$output} > /dev/null 2>&1 & echo $!"; $pid = shell_exec($command); return response()->json(['status' => 'processing', 'pid' => trim($pid)]); });此时即使 FFmpeg 运行 15 分钟,访问
/api/status或刷新首页仍即时响应。
? 补充建议:
- 使用队列(如
redis+horizon)替代裸shell_exec,提升可观测性与错误重试能力; - 若必须用
artisan serve临时调试,可启用--host=0.0.0.0 --port=8000并配合&后台执行 +ignore_user_abort(true),但仅限调试,切勿用于多用户测试; - 检查
php.ini中max_execution_time和set_time_limit(0)的使用场景——它们控制脚本生命周期,但不解决服务器并发瓶颈。
总结:php artisan serve 是轻量开发工具,非生产就绪服务器。当涉及长时任务时,应尽早切换至 Apache/Nginx 环境,这才是根治请求阻塞的根本路径。


















