Laravel+Supervisor环境下SMTP异常致主进程报错问题求助
问题解决步骤
1. 补全.env队列核心配置
问题根源之一是默认队列驱动为sync,这会让事件/监听器在主线程同步执行,SMTP异常直接抛出到主请求导致500。需配置异步驱动:
示例(Database驱动):
# 必须设置为异步驱动(database/redis等,禁止用sync) QUEUE_CONNECTION=database # 队列重试超时时间(单位:秒) QUEUE_RETRY_AFTER=90 # 失败任务存储表名(默认即可) QUEUE_FAILED_TABLE=failed_jobs # 可选:指定队列名称 QUEUE_NAME=email-sending
示例(Redis驱动):
QUEUE_CONNECTION=redis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379
配置后执行队列表迁移(Database驱动必填):
php artisan queue:table php artisan queue:failed-table php artisan migrate
2. 给监听器添加异常捕获
即使队列异步执行,未捕获的SMTP异常会导致队列任务失败,但不会影响主请求。为了更稳健,在监听器中捕获异常并记录日志:
修改ClientRequestSubmitListener.php的handle方法:
public function handle(ClientRequestSubmitEvent $event) { try { Mail::to('test@test.com')->send(new ClientRequestSubmitMail($event)); } catch (\Exception $e) { // 记录错误日志 \Log::error('客户请求提交邮件发送失败', [ 'error' => $e->getMessage(), 'user_id' => $event->userId, 'client_id' => $event->clientId ]); // 可选:若需队列自动重试,取消下面注释 // throw $e; } }
3. 确保事件异步分发配置(可选)
在事件类中显式指定队列参数,避免配置冲突:
修改ClientRequestSubmitEvent.php,添加以下属性:
// 指定队列连接(与.env的QUEUE_CONNECTION一致) public $connection = 'database'; // 指定队列名称(与.env的QUEUE_NAME一致) public $queue = 'email-sending';
4. 验证Supervisor队列Worker配置
确保Supervisor的启动命令正确指向异步驱动,示例配置:
[program:laravel-email-queue] process_name=%(program_name)s_%(process_num)02d # 替换为你的项目路径,驱动与.env保持一致 command=php /var/www/your-project/artisan queue:work database --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true user=www-data numprocs=2 redirect_stderr=true stdout_logfile=/var/www/your-project/storage/logs/queue-worker.log stopwaitsecs=3600
重启Supervisor使配置生效:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-email-queue:*
5. 测试验证
触发事件后,检查:
- 主请求是否返回200(无500错误)
jobs表(Database驱动)是否生成任务记录- 队列Worker日志是否正常处理任务
- 失败任务会存入
failed_jobs表,可通过php artisan queue:retry all重新执行
内容的提问来源于stack exchange,提问作者Ronak Solanki
相关产品推荐
相关产品推荐

