Laravel使用database驱动队列任务显示已处理但未执行Curl上传如何排查
问题根因与解决方案
核心问题原因
- 路径不匹配:Web请求层仅将文件名传递给队列任务,队列进程的运行根目录和Web请求进程不一致,仅通过文件名无法定位到上传后的物理文件,CURL读取文件失败但无错误抛出
- env变量读取失效:Laravel执行
php artisan config:cache后,队列独立进程无法直接读取env()函数返回的配置值,仅同步请求内可以正常读取,导致上传接口的Authorization头为空请求失败 - 缺少错误捕获逻辑:你的CURL执行后未做任何错误判断,即使请求失败也不会抛出异常,队列系统默认认为任务执行成功,直接标记为已处理不会产生报错日志
- (可选)未启动队列消费进程:切换为database驱动后需要手动启动队列消费命令,sync驱动是同步执行不需要单独启动进程
修复步骤
1. 传递完整绝对文件路径
修改上传逻辑,传递文件完整路径而非仅文件名:
// 原代码 $file->move(base_path('public'),$filename); UploadFile::dispatch($filename, $this->url); // 修改为 $fullPath = base_path('public/'.$filename); $file->move(base_path('public'),$filename); UploadFile::dispatch($fullPath, $this->url);
2. 替换env调用为config调用
首先在config/services.php中新增配置项:
return [ // 其他原有配置 'custom_api' => [ 'key' => env('API_KEY'), ], ];
然后修改Job中获取密钥的逻辑:
// 原代码 'Authorization: Bearer ' . env('API_KEY') // 修改为 'Authorization: Bearer ' . config('services.custom_api.key')
3. 增加错误捕获与日志
修改Job中的upload方法,增加错误判断,出现问题直接抛出异常让队列标记任务失败,方便排查:
public function upload(){ // 先打印参数到日志确认参数正确性 \Log::info('上传任务参数', [ 'file_path' => $this->filename, 'upload_url' => $this->url, 'api_key' => config('services.custom_api.key') ]); // 校验文件是否存在 if (!file_exists($this->filename)) { throw new \Exception('上传文件不存在:'.$this->filename); } $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $this->url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => array('did' => 0,'file[]'=> new \CURLFILE($this->filename)), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . config('services.custom_api.key') ), )); $response = curl_exec($curl); // 捕获CURL错误 if (curl_errno($curl)) { $error = curl_error($curl); curl_close($curl); throw new \Exception('CURL请求错误:'.$error); } // 捕获接口返回错误 $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($httpCode < 200 || $httpCode >= 400) { throw new \Exception('上传接口返回错误码:'.$httpCode.', 返回内容:'.$response); } }
4. 启动队列进程调试
执行以下命令启动临时队列消费进程,输出详细执行日志:
php artisan config:clear # 先清除旧的配置缓存 php artisan queue:restart # 重启队列进程,加载新代码 php artisan queue:work --tries=1 --verbose
此时执行上传任务,就能在控制台或者storage/logs/laravel.log里看到具体的错误原因了。
内容的提问来源于stack exchange,提问作者Alexandru Popa
相关产品推荐
相关产品推荐

