Laravel队列没有在后台工作



我正在尝试使用laravel队列发送批量电子邮件。到目前为止,我已经写下了逻辑,它工作得很好,但问题是,当我在控制器中写逻辑时,它需要很多时间,所以我想使用作业,但问题仍然存在。

我的问题

我的问题是,即使我使用队列,我也无法在后台发送电子邮件。

控制器

public function newsletter(Request $request)
{
//dd($request->all());
dispatch(new SendEmail($request));
Session::flash('message', 'Email Sent');
Session::flash('class', 'success');
return redirect()->route('news');
}

工作

public function handle(Request $request)
{
//
$data = array(
'message' => $request->message,
'subject' => $request->subject,
'file' => $request->file("file")
);

$teachingLevel = $request->highest_teaching_level;
$school = $request->school;
$province = $request->province;
$district = $request->district;
$subject = $request->subject;
if ($teachingLevel != "" && $school != "" && $province != "" && $district != "") {
$email = User::where('highest_teaching_level', $teachingLevel)->where('current_school_name', $school)->where('address','LIKE', '%'.$province.'%')->where('address','LIKE', '%'.$district.'%')->pluck('email');
}else{
$email = User::pluck('email');
}

foreach($email as $e)
{
Mail::to($e)->send(new NewsLetter($data, $subject));
}
}

电子邮件已发送,但不会在后台发生。也许这与我在handle()函数中传递$request变量的方式有关。

任何帮助都将不胜感激。谢谢

以下是我如何在项目中使用Laravel作业:

SampleJob.php

namespace AppJobs;
use IlluminateBusQueueable;
use IlluminateQueueSerializesModels;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use AppServicesSampleService;
class SampleJob implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

// if you omit this value, you'll be in trouble, believe me
public $tries = 1; 
private $param;
public function __construct($param) {
$this->param = $param;
}
public function handle(SampleService $service) {
// do something with $this->param
// Also, notice that you can type hint classes in handle function declaration for DI
$service->doSomething($this->param);
}

}

SampleController.php


namespace AppHttpControllers;
use AppJobsSampleJob;

class SampleController extends Controller {

public function sampleMethod(Request $request) {
$param = $request->input('param');
SampleJob::dispatch($param); // $param will be passed to SampleJob constructor
// ...
}
}

值得注意的几点是:

  • 阅读我的代码片段中的注释
  • 如果使用基于数据库的队列,请首先使用php artisan queue:table && php artisan migrate进行迁移
  • 使用artisan命令创建作业:php artisan make:job Sample
  • 不要忘记运行队列工作程序:php artisan queue:work。使其在后台运行:sudo nohup php artisan queue:work > ./storage/logs/queue-worker.log &
  • 强烈建议:在部署中,使用Supervisor保持php artisan queue:work在后台运行
  • 如果您设法使作业工作,则所有延迟的(由于配置错误或未启动队列工作者而排队但未处理的(工作都将立即执行

常见陷阱:

  • 如果您没有设置$tries参数,并且您的作业以某种方式抛出错误,laravel将尝试一次又一次地重试该作业,直到您的数据库关闭:(
  • 如果http用户和php用户不同,并且您在工作中使用了Log,那么十次中有九次您会面临storage目录的权限问题。要避免此问题,请将'permission' => '0666'添加到config/logging.php中的日志通道设置中
  • 队列工作程序不会检测到您的代码更改,因此在您对代码库进行一些更改后,通过php artisan queue:restart重新启动队列工作程序

我的laravel版本:5.8

如果要使用"数据库"连接,则需要运行下一次迁移:

php artisan queue:table
php artisan migrate

还有一个Event和一个Listener,它实现了"ShouldQueue"接口,最后在"providers/EventProvider.php"路径和"EventProvider.php"文件中注册与一个或多个侦听器关联的事件时,使用下一个符号添加您的事件和侦听器,例如:

protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];

重要的是要理解与以下队列相关的几点:重新启动命令

php artisan queue:restart

要实现这一点,您需要运行队列侦听器:

php artisan queue:listen

参考编号:https://medium.com/ariel-mejia-dev/run-queues-in-the-background-on-development-in-laravel-8d697d812f29