Lumen 5.5 Redis邮件队列不生效,如何实现异步发件?
解决Redis队列异步发送邮件不生效的问题
看起来你已经搭好了基础流程,但队列还没真正跑起来,导致邮件还是同步发送。咱们一步步排查修复:
1. 让EmailJob实现队列接口
这是最核心的问题!你的EmailJob目前只是继承了Job类,但没有明确实现ShouldQueue接口——这会导致dispatch()直接同步执行这个Job,根本不会把它丢进Redis队列。修改你的Job类:
namespace App\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Bus\Queueable; class EmailJob extends Job implements ShouldQueue { use Queueable; // 可选但推荐,方便后续设置队列名、延迟执行等 public function __construct() { } public function handle() { Mail::to("sendmailto@gmail.com")->send(new \App\Mail\CompleteOrder("Sending")); } }
加上implements ShouldQueue后,Laravel才会把这个Job推送到Redis队列,而非立即执行。
2. 检查队列配置的兼容性
- 如果你用的是Laravel 8及以上版本,
.env里的配置项已经从QUEUE_DRIVER改成了QUEUE_CONNECTION,所以要更新为:QUEUE_CONNECTION=redis - 确保Redis服务正在运行,同时
.env里的Redis连接配置(REDIS_HOST、REDIS_PORT等)正确,能正常连接到你的Redis实例。
3. 正确启动队列监听
运行队列监听时,最好明确指定Redis连接,避免Laravel读取旧的缓存配置(比如默认的sync驱动):
php artisan queue:work redis
如果之前已经启动过queue:work,一定要重启它——因为队列进程会加载启动时的配置,修改.env后必须重启才能生效。
可选优化:直接队列化邮件(省去Job类)
其实你已经给CompleteOrder邮件类加了Queueable trait和ShouldQueue接口,完全可以不用封装Job类,直接在路由里异步发送邮件,代码更简洁:
$router->get('/email-with-queue', function () use ($router) { Mail::queue(new \App\Mail\CompleteOrder("Sending")); return ['sending mail..']; });
验证效果
- 访问接口
http://xxx.dev/email-with-queue,现在应该瞬间返回sending mail..,不会再等待10秒; - 查看
queue:work redis的控制台输出,会出现类似Processing: App\Jobs\EmailJob的日志,之后邮件就会异步发送完成; - 如果还是没输出,用
redis-cli连接你的Redis,执行KEYS laravel:*,看看是否存在laravel:queues:default这类key——如果有,说明队列里已经有任务,只是监听进程没连上,检查Redis配置或重启监听即可。
内容的提问来源于stack exchange,提问作者teguh11
相关产品推荐
相关产品推荐

