必须将高清图片压缩与格式转换移至laravel队列异步执行,配置redis驱动、启动queue:work常驻进程,定义processuploadedimage任务类处理图片(缩放至宽1200px、质量80%、转webp),通过dispatch分发任务并设置重试与失败处理机制。

当用户上传高清图片时,直接在请求响应周期内完成压缩和格式转换会导致页面卡顿、超时甚至502错误,必须将耗时操作移出主流程交给Laravel队列异步执行。
配置队列驱动与连接
编辑 config/queue.php,将默认驱动设为 redis:把 'default' => env('QUEUE_CONNECTION', 'sync') 改为 'default' => env('QUEUE_CONNECTION', 'redis')。
确保 .env 文件中已设置 QUEUE_CONNECTION=redis 且 Redis 服务正在运行;若未启用 Redis,【队列任务将静默失败,不会报错但也不会执行】。
运行 php artisan queue:work --daemon 启动常驻工作进程,该命令需配合 Supervisor 管理,避免终端关闭后进程终止。
定义图片处理任务类
执行命令生成任务类:php artisan make:job ProcessUploadedImage。
打开生成的 app/Jobs/ProcessUploadedImage.php,在 handle() 方法中引入 Intervention Image:先用 use Illuminate\Support\Facades\Storage; 和 use Intervention\Image\Facades\Image;,再读取原始图片 → 调整尺寸至宽度 1200 像素(保持宽高比)→ 质量压缩至 80 → 转换为 WebP 格式 → 保存到 public/images/processed/ 目录。
注意:不要在 handle() 中使用 dd() 或 dump(),这会导致队列卡死且无法重试。
触发队列任务
在控制器接收上传文件后,跳过同步处理,直接分发任务:
方法一:立即推入队列ProcessUploadedImage::dispatch($request->file('image'), $userId);
方法二:延迟 3 秒后再执行(适合避开瞬时并发高峰)ProcessUploadedImage::dispatch($request->file('image'), $userId)->delay(now()->addSeconds(3));
方法三:指定连接与队列名,便于资源隔离ProcessUploadedImage::dispatch($request->file('image'), $userId)->onConnection('redis')->onQueue('image-processing');
监控与重试策略
第一步:在任务类顶部添加 public $tries = 3;,防止因临时网络抖动或磁盘满导致的单次失败直接丢弃。
第二步:重写 failed() 方法,记录失败详情到日志并通知管理员:Log::error("Image processing failed for user {$this->userId}: {$exception->getMessage()}");
第三步:使用 Horizon(推荐)或 Laravel Scout 配套工具查看任务状态;若发现大量 pending 任务堆积,检查 Redis 内存是否充足、queue:work 进程是否存活。











