// public $connection = 'database';
// public $queue = 'listeners'; //不能加,加了就不触发
public $delay = 60;
先直接上答案,我测试在监听器里把 public $queue = 'listeners'; 属性添加后,异步队列就不执行的情况。
官方文档也有这个属性,不清楚什么原因,反正注释就好了。
下面上laravel 事件+监听器+异步队列的步骤:
我的环境是 homestead+php7.4+laravel8
前提条件:
写异步队列,如果是database异步队列模式
需要先安装数据库:
php artisan queue:table //生成数据库队列的
migration php artisan migrate //创建该数据库队列表
数据库里会自动生成的表
在.env里设置:
QUEUE_CONNECTION=database
如果是redis模式
在.env里设置:
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis
业务逻辑:用户登录,登录事件触发两个监听器。具体代码都是写的简单日志。
第一步:
先在app/Providers/EventServiceProvider.php文件里写事件和监听的管理
class EventServiceProvider extends ServiceProvider
protected $listen = [
// Registered::class => [
// SendEmailVerificationNotification::class,
// ],
//用户登录事件
'App\Events\User\LoginEvent' => [
'App\Listeners\User\LogListeners',
'App\Listeners\User\SendSmsListeners',
第二步:在homestead 命令行里输入:php artisan event:generate
自动生成事件文件和监听文件
第三步:我们把控制器创建好。省略
UserInfoController.php
use App\Events\User\LoginEvent;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class UserInfoController extends Controller
public function login()
Log::debug('用户的登录');
$username = 'luo';
//未延迟执行
event(new LoginEvent($username)); //触发LoginEvent事件 就这句有用
return 'ok';
第四步:配置路由访问控制器 省略
$router->post('login','UserInfoController@login');
第五步:编写事件文件:LoginEvent.php和监听文件LogListeners.php、SendSmsListeners.php
LoginEvent.php事件文件,一般这里面不写具体逻辑,就传个参数、对象
class LoginEvent
use Dispatchable, InteractsWithSockets, SerializesModels;
protected $userName;
public function __construct($userName)
return $this->userName = $userName;
public function getUserName()
return $this->userName;
LogListeners.php、SendSmsListeners.php监听器,真正写代码的文件
LogListeners.php 为了区分这里面没有异步队列
class LogListeners
public function __construct()
public function handle(LoginEvent $event)
$now = now();
Log::debug($event->getUserName().'进入监听程序:'.$now);
SendSmsListeners.php监听器延时60秒执行
use Illuminate\Support\Facades\Log;
class SendSmsListeners implements ShouldQueue
use InteractsWithQueue;
// public $connection = 'database';
// public $queue = 'listeners'; //不能加,加了就不触发
public $delay = 60;
public function __construct()
public function handle(LoginEvent $event)
$now = now();
Log::debug('延迟执行:'.$now);
// public $queue = 'listeners'; 这个变量我是注释的
第六步:homestead里运行队列命令: php artisan queue:listen
访问接口就会触发队列(测试的延时时间$delay=10,难得等)
看看日志吧
laravel.log
有不对的地方请指正,共同学习共同成长