本文目录导读:

在Laravel中配置邮件队列发送是一个常见的需求,我来详细说明完整的配置步骤:
基础配置
环境配置 (.env文件)
# 邮件配置
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME="${APP_NAME}"
# 队列配置(推荐使用 Redis 或数据库)
QUEUE_CONNECTION=database
# 或
QUEUE_CONNECTION=redis
数据库驱动配置(最简单)
生成迁移文件
php artisan queue:table php artisan migrate
创建邮件类
php artisan make:mail OrderShipped
实现示例
创建邮件类(app/Mail/TestQueueMail.php)
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class TestQueueMail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this
->from(config('mail.from.address'), config('mail.from.name'))
->subject('测试队列邮件')
->view('emails.test')
->with(['data' => $this->data]);
}
}
创建邮件视图(resources/views/emails/test.blade.php)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">测试邮件</title>
</head>
<body>
<h1>这是一封队列测试邮件</h1>
<p>发送时间:{{ now() }}</p>
<p>数据内容:{{ $data['message'] ?? '默认内容' }}</p>
</body>
</html>
发送邮件的三种方式
延迟发送(推入队列)
use App\Mail\TestQueueMail;
public function sendMail(Request $request)
{
$data = ['message' => '这是测试邮件内容'];
$recipient = 'recipient@example.com';
// 推入队列发送
Mail::to($recipient)->queue(new TestQueueMail($data));
// 延迟5分钟发送
Mail::to($recipient)->later(now()->addMinutes(5), new TestQueueMail($data));
// 也可以使用 Job 方式
dispatch(new SendMailJob($recipient, $data));
return response()->json(['status' => 'success', 'message' => '邮件已在队列中']);
}
创建专用Job
php artisan make:job SendMailJob
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use App\Mail\TestQueueMail;
class SendMailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $recipient;
protected $data;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($recipient, $data)
{
$this->recipient = $recipient;
$this->data = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try {
Mail::to($this->recipient)->send(new TestQueueMail($this->data));
\Log::info('邮件发送成功', [
'recipient' => $this->recipient,
'time' => now()
]);
} catch (\Exception $e) {
\Log::error('邮件发送失败', [
'recipient' => $this->recipient,
'error' => $e->getMessage()
]);
// 如果失败,重新尝试3次
if ($this->attempts() < 3) {
$this->release(10); // 10秒后重试
}
}
}
/**
* 定义失败回调
*/
public function failed(\Throwable $exception)
{
\Log::error('邮件发送最终失败', [
'recipient' => $this->recipient,
'error' => $exception->getMessage()
]);
}
}
实现 ShouldQueue 接口
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class TestQueueMail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
// 其他代码...
// 设置队列连接
public $connection = 'database';
// 设置队列名称
public $queue = 'emails';
// 设置延迟时间
public $delay = 0;
// 设置重试次数
public $tries = 3;
// 设置超时时间(秒)
public $timeout = 60;
}
启动队列工作者
# 基本启动 php artisan queue:work # 指定队列 php artisan queue:work --queue=emails # 指定连接 php artisan queue:work database --queue=emails # 后台守护进程运行 php artisan queue:work --daemon # 只处理一次任务 php artisan queue:work --once # 配合 Supervisor 使用(生产环境推荐)
Supervisor 配置(生产环境)
创建文件 /etc/supervisor/conf.d/laravel-worker.conf:
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=8 redirect_stderr=true stdout_logfile=/var/www/html/storage/logs/worker.log stopwaitsecs=3600
失败任务处理
# 查看失败任务 php artisan queue:failed # 重试失败任务 php artisan queue:retry all # 删除失败任务 php artisan queue:forget all # 清空失败任务 php artisan queue:flush
高级配置
多个邮件配置
// config/mail.php
return [
'mailers' => [
'smtp' => [...],
'sendmail' => [...],
'mailgun' => [...],
'ses' => [...],
'postmark' => [...],
'log' => [...],
'array' => [...],
'failover' => [
'transport' => 'failover',
'mailers' => ['smtp', 'mailgun'],
],
],
];
邮件队列监控
// 使用 Laravel Horizon(推荐用于 Redis) composer require laravel/horizon php artisan horizon:install php artisan migrate
测试邮件
// 在测试环境使用 array 驱动,不会真正发送邮件 MAIL_MAILER=array // 记录到日志 MAIL_MAILER=log
注意事项
- 生产环境一定要使用 Supervisor 或进程管理工具监控队列进程
- 及时处理失败任务,避免邮件积压
- 设置合适的重试次数和超时时间
- 使用日志记录邮件发送的状态
- 考虑使用邮件服务商的 API 接口(如 Mailgun、SES)提高发送效率
- 批量邮件建议使用单独专用队列
这样就完成了 Laravel 邮件队列发送的完整配置,根据实际需求选择最简单的配置方式即可。