mysql消息队列推送到redis_laravel基于redis,使用消息队列(邮件推送)

高性能离不开异步,异步离不开队列。

下面将介绍Laravel框架怎么使用队列进行一些异步处理。

在系统很多模块可能同步处理需要很长时间,比如发送邮件、视频转码、日志存储等。

假如系统处理这些功能模块都是使用同步处理的话,那么系统性能必将大大降低。

所以我们可以考虑异步进行处理这些长进程任务。

下面将介绍laravel的队列,即可以实现异步处理这些任务。

关于队列入门知识可以参考《[redis消息队列简单应用](http://blog.yxccan.cn/blog/detail/3 "redis消息队列简单应用")》

#### 概括

1. laravel队列配置(配置文件 .env 和 config/queue.php)

2. 创建队列任务类(app/Jobs/xxx.php)

3. 控制器将数据添加到队列中

4. 启动队列

5. 设置API路由,执行请求,执行队列任务

6. 使用Supervisor将队列任务启动 添加到守护进程中

------------

### 1. laravel队列配置(配置文件 .env 和 config/queue.php)

优先配置文件 .env 如下:

```php

QUEUE_DRIVER=redis #队列驱动 更改使用 redis

# 其它不设置 则会使用 config/queue.php 里面的配置参数

```

当.env 文件没有配置 或者 设置变量为空时,则会按照 config/queue.php 文件的配置信息运行laravel

config/queue.php 文件如下:

```php

'default' => env('QUEUE_DRIVER', 'redis'), //修改队列驱动,使用redis

'connections' => [

//...省略其它驱动

//redis驱动

'redis' => [

'driver' => 'redis',

'connection' => 'email', //连接redis的配置 email节点

'queue' => 'default', //默认使用default队列 键名

'retry_after' => 90, //该配置项的目的是定义任务在执行以后多少秒后释放回队列

'block_for' => null,

],

],

'failed' => [

'database' => env('DB_CONNECTION', 'mysql'),//队列执行失败 存放的数据库

'table' => 'failed_jobs',//队列执行失败 存放的表

],

```

### 2. 创建队列任务类(app/Jobs/xxx.php)

在app/Jobs 目录下创建执行队列任务的类,若没有Jobs文件夹,则可以自己创建;

或者使用artisan命令 创建队列任务类,命令如下:

php artisan make:job SendEmailCode

执行后,将会生成 app/Jobs/SendEmailCode.php

其中handle()方法为任务执行方法,如下代码为发送邮件的源码:

app/Jobs/SendEmailCode.php 代码如下:

```php

data = $data;

}

/**

* @param Mailer $mailer

*/

public function handle(Mailer $mailer)

{

$data = $this->data;

$mailer->end('email.sendCode', ['data' => $data], function ($message) use ($data) {

$message->to($data['email'])->subject('【' . $data['code'] . '】重要操作验证码 - YXC-Blog');

});

}

}

```

代码解析:其中handle中执行了发送邮件的方法Mailer类下的send()方法,详情可以阅读《[laravel 通过smtp发送邮件配置、相关示例](http://blog.yxccan.cn/blog/detail/4 "laravel 通过smtp发送邮件配置、相关示例")》

$data:为规定的数组数据,需要控制器调用添加队列时传值过来。

### 3. 控制器将数据添加到队列中

创建一个控制器,将数据添加到队列中

在app/Http/Controllers/目录下创建MailController.php 文件

或者使用artisan 命令进行创建

如下是发送验证码的控制器代码:

```php

get('email');

$resArray = [

'code' => 0,

'msg' => '发送成功'

];

if (preg_match('/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,5}){1,2})$/', $email)) {

$resArray['code'] = 1;

$data['email'] = $email;

$data['code'] = mt_rand(1000, 999999);

//...其它操作

//添加邮件队列

$this->dispatch((new SendEmailCode($data))->onQueue('sendEmailCode'));

} else {

$resArray['msg'] = '邮箱格式不正确';

}

return $resArray;

}

}

```

代码解析:

$this->dispatch((new SendEmailCode($data))->onQueue('sendEmailCode'));

其中dispatch()方法为分发任务的核心方法,方法里传一个任务类的实例。

3.1) dispatch()->onConnection('database') :更改任务的连接,将连接数据库进行存储队列

3.2) ->onQueue('sendEmailCode') :更改使用的队列名称

3.3) ->delay(now()->addMinutes(10)) :创建后延迟10分钟执行队列

### 4. 启动队列

Laravel 自带了一个队列进程用来处理被推送到队列的新任务。你可以使用 queue:work 命令运行这个队列进程。请注意,队列进程开始运行后,会持续监听队列,直至你手动停止或关闭终端

请记住,队列进程是长生命周期的进程,会在启动后驻留内存。若应用有任何改动将不会影响到已经启动的进程。所以请在发布程序后,重启队列进程。

最简单的启动命令:

php artisan queue:work

但是以上命令,只会执行default队列,所以不是我们实际想要的。所以需要以下启动命令

4.1 php artisan queue:work --queue=sendEmailCode

指定启动sendEmailCode队列

4.2 php artisan queue:work redis --queue=emails

指定启动redis连接下的sendEmailCode队列

4.3 php artisan queue:work --queue=higher,high,low ...

指定队列执行的优先级

4.4 php artisan queue:restart

重启队列

4.5 php artisan queue:work --timeout=60

队列进程 queue:work 可以设定超时 --timeout 项。该 --timeout 控制队列进程执行每个任务的最长时间,如果超时,该进程将被关闭。

注:参数项 --timeout 的值应该始终小于配置项 retry_after 的值,这是为了确保队列进程总在任务重试以前关闭。如果 --timeout 比retry_after 大,那么你的任务可能被执行两次。

4.6 php artisan queue:work --sleep=3

休眠时间,每执行一个任务后休眠3秒

4.7 启动监听三种情况:

4.7.1 queue:work

默认只执行一次队列请求, 当请求执行完成后就终止;

4.7.2 queue:listen

监听队列请求, 只要运行着, 就能一直接受请求, 除非手动终止;

4.7.3 queue:work --daemon

同 listen 一样, 只要运行着, 就能一直接受请求, 不一样的地方是在这个运行模式下, 当新的请求到来的时候, 不重新加载整个框架, 而是直接 fire 动作.

能看出来, queue:work --daemon 是最高级的, 一般推荐使用这个来处理队列监听.

注意: 使用 queue:work --daemon , 当更新代码的时候, 需要停止, 然后重新启动, 这样才能把修改的代码应用上

### 5. 设置API路由,执行请求,执行队列任务

在 routes/api.php 设置 刚刚的邮件控制器的路由

代码如下:

```php

//发送邮箱验证码

Route::post('sendEmailCode', 'MailController@sendEmailCode');

```

如下我们使用postman发送post请求即可以测试发送邮件队列了

请求地址 //localhost/api/sendEmailCode

![](https://blog-1252087744.cos.ap-guangzhou.myqcloud.com/2019-04/laravel%E5%9F%BA%E4%BA%8Eredis%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%EF%BC%88%E9%82%AE%E4%BB%B6%E6%8E%A8%E9%80%81%EF%BC%89/1.jpg)

观察redis是否有队列数据

![](https://blog-1252087744.cos.ap-guangzhou.myqcloud.com/2019-04/laravel%E5%9F%BA%E4%BA%8Eredis%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%EF%BC%88%E9%82%AE%E4%BB%B6%E6%8E%A8%E9%80%81%EF%BC%89/2.jpg)

观察进程,我这边使用windows的测试

![](https://blog-1252087744.cos.ap-guangzhou.myqcloud.com/2019-04/laravel%E5%9F%BA%E4%BA%8Eredis%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%EF%BC%88%E9%82%AE%E4%BB%B6%E6%8E%A8%E9%80%81%EF%BC%89/3.jpg)

成功,邮件也收到了

![](https://blog-1252087744.cos.ap-guangzhou.myqcloud.com/2019-04/laravel%E5%9F%BA%E4%BA%8Eredis%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%EF%BC%88%E9%82%AE%E4%BB%B6%E6%8E%A8%E9%80%81%EF%BC%89/4.jpg)

### 6. 使用Supervisor将队列任务启动 添加到守护进程中

推荐安装Supervisor,将 php artisan queue:work --queue sendEmailCode 等一系列队列进程,添加到进程保护中,防止中途崩溃时候,可以自救,哈哈~😄

关于Supervisor,可以参考《[centos安装Supervisor以及简单配置(添加进程守护)](http://blog.yxccan.cn/blog/detail/32 "centos安装Supervisor以及简单配置(添加进程守护)")》

------------

#### 总结

1. laravel队列配置(配置文件 .env 和 config/queue.php)

2. 创建队列任务类(app/Jobs/xxx.php)

3. 控制器将数据添加到队列中

4. 启动队列

5. 设置API路由,执行请求,执行队列任务

6. 使用Supervisor将队列任务启动 添加到守护进程中

------------

the End.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值