You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8.55队列处理S3上传文件生产环境报文件不存在错误

Laravel 8 队列任务Heroku部署时Laravel-Excel报文件不存在故障排查

问题背景

接手的项目基于Laravel 8.55开发,包含一个网页上传CSV触发的队列任务,执行流程如下:

  • CSV文件上传至S3存储桶
  • 借助Laravel-Excel完成文件解析处理,更新对应数据库条目
  • 向用户发送任务完成通知邮件
  • 删除S3中存储的原始CSV文件

本地开发环境为Windows11(PhpStorm)+ MySQL,使用php artisan serve作为Web服务器,该队列任务在本地运行完全符合预期。

故障现象

部署到Heroku生产环境后:

  • 文件可成功上传至目标S3存储桶
  • 后续队列任务执行失败,失败记录写入failed_jobs表
  • Bugsnag上报错误信息如下:
Illuminate\Contracts\Filesystem\FileNotFoundExceptionMaatwebsite\Excel\Jobs\ReadChunk
File not found at path: laravel-excel-3svOWxojWikYEuWZuBBBHlbXl6WpK7Xb.csv

触发该任务的上传代码片段:

$file = $request->file('filename');
$f_ori_name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$file_name = Str::random(40).'.'.$extension;
$tmp_path = Storage::disk('s3_temp')->put($file_name, file_get_contents($file->getRealPath()));
$path = Storage::disk('s3_temp')->path($file_name);

$var = (new MembersImport($currentPerson, $import_detail))->queue($path, 's3_temp')
                ->chain([
                    new ImportDetailsUpdateJob($import_detail),
                    new NotifyUserOfCompletedImport($currentPerson, $import_detail),
                    function () use ($path) {
                        Storage::disk('s3_temp')->delete($path);
                    }
                ])->onConnection('database')
                ->onQueue('default');

故障根因

  1. Heroku的dyno文件系统是临时隔离的:Web dyno和Queue Worker dyno的本地文件系统不共享,Laravel-Excel默认会将远程文件拉取到本地临时目录生成laravel-excel-xxx.csv格式的临时分块文件,Web进程生成的临时文件Worker进程完全无法访问。
  2. 代码中对S3磁盘错误调用了path()方法:S3作为对象存储不存在本地绝对路径概念,path()返回的本地路径在Worker进程中无对应有效文件。
  3. 队列链中的删除逻辑引用了错误的路径变量,可能触发提前删除文件的逻辑。

修复方案

  • 修正S3文件传参逻辑:删除$path = Storage::disk('s3_temp')->path($file_name);的赋值,调用queue()方法时第一个参数直接传S3对象key也就是$file_name即可,因为第二个参数已经指定磁盘为s3_temp,Laravel-Excel会自动通过S3 API读取对象,不需要本地路径。
  • 修改Laravel-Excel临时文件配置:打开config/excel.php,找到temporary_files配置项,将临时文件磁盘设置为S3共享存储,避免使用本地临时目录导致跨dyno访问失败,配置参考:
'temporary_files' => [
    'local_path' => storage_path('framework/cache/laravel-excel'),
    'disk' => 's3_temp', // 替换为你的S3临时存储磁盘名
],
  • 修正队列链的删除逻辑:删除闭包中传入的$path变量,直接使用$file_name作为删除参数,即Storage::disk('s3_temp')->delete($file_name);,避免路径错误导致的误删或者删除失败。
  • 校验Heroku环境配置:确认Queue Worker dyno的环境变量(尤其是S3访问密钥、区域、桶名配置)和Web dyno完全一致,同时确认config/filesystems.php中s3_temp磁盘生产环境使用s3驱动而非本地驱动。

内容的提问来源于stack exchange,提问作者Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:39:17