在不少项目业务复杂到必定程度、项目大到必定程度,就都是一些重构、优化、升级等手段,让项目更稳健;能抵挡更强的“风暴”。而
异步服务器
则也是减轻服务器压力,提升项目性能的一个常见手段之一,把一些实时性不强,并且量还比较大的业务能够异步
来解决。临近年末了,丢丢哥最近工做比较忙,博客更新少了点。见谅php
异步消息队列
简要的介绍下同步消息队列本篇博客为了更明确异步消息队列
和同步消息队列
的实现原理 以MySQL
消息队列为示例,可是在真正的项目中(若是没有单独的异步服务器,则建议使用Redis
消息队列)css
Laravel
的队列服务为不一样的队列后端系统提供了一套统一的 API
。队列容许你将一个耗时的任务进行延迟处理,例如像 e-mail
发送。这能让应用程序对页面的请求有更快的响应。mysql
队列的配置文件被保存在 config/queue.php
中。可是Laravel
中优先选用.env
的配置在这个文件内你能够找到包含在 Laravel
中的每一种队列驱动链接设置。它们包含了数据库、Beanstalkd、IronMQ、Amazon SQS、Redis 以及提供本机使用的 synchronous 驱动。laravel
.env配置同步:sql
.env配置异步:数据库
另外框架也提供了 null 这个队列驱动用来丢弃队列任务。后端
本实例中是用群发email的实例,若是模仿,请配置本身的邮件服务
服务器
php artisan queue:table php artisan queue:failed-table php artisan migrate
php artisan make:job SendUserEmail --queued
而后在项目的App\Jobs
里面会生成一个SendUserEmail.php
文件框架
接下来 咱们再生成一个控制器UserController
异步
php artisan make:controller UserController --resource
routes.php
Route::resource('/user','UserController');
UserController
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Jobs\CreateMessage; use App\Jobs\SendUserEmail; class UserController extends Controller { ... ... /** * 这个方法咱们用来模拟发送消息队列. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // $datas = \DB::table('user')->where('status',1)->get(); foreach($datas as $data){ $job = (new SendUserEmail($data->name,$data->email)); $this->dispatch($job); } return redirect('/user'); }
SendUserEmail.php
<?php namespace App\Jobs; use App\Jobs\Job; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Bus\SelfHandling; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Support\Facades\Mail; class SendUserEmail extends Job implements SelfHandling, ShouldQueue { use InteractsWithQueue, SerializesModels; protected $name; protected $email; /** * Create a new job instance. * * @return void */ public function __construct($name, $email) { // $this->name = $name; $this->email = $email; } /** * Execute the job. * * @return void */ public function handle() { // 若是参试大于三次 if ($this->attempts() > 3) { \Log::info($this->name.'邮件参试失败过多'); }else{ // 每次进来休息3秒钟 sleep(3); // 休息10秒钟 //$this->release(10); $url = 'http://www.ydma.cn'; $title = '测试邮件'; $to = $this->email; // 邮件发送 $flag = Mail::send('email.test', ['name' => $this->name, 'url' => $url], function ($message) use ($to, $title) { // 发送 $message->to($to)->subject('【亲爱的程序猿】' . $title); }); echo date('Y-m-d H:i:s')."\n".$to.'的邮件已发送...'; if($flag){ \Log::info($this->name.'邮件发送成功'); }else{ \Log::info($this->name.'邮件发送失败'); } } } /** * 处理一个失败的任务 * * @return void */ public function failed() { \Log::error($this->name.'队列任务执行失败'."\n".date('Y-m-d H:i:s')); } }
1.咱们env是设置的database
(异步消息队列)
2.开启队列监听
php artisan queue:listen
3.或者 开启后台监听(不影响本身输入其余命令)
php artisan queue:listen &
4.也能用work 后面参数是休息时间和尝试次数
php artisan queue:work connection --daemon --sleep=3 --tries=3
5.访问网址(这个网址是我本身本地的)
6.而后看个人Mysql的变化jobs表原本有8条队列数据须要处理
7.而后看终端监听的变化
8.消息队列被一条条的推送..反观数据库jobs的变化,发现被清空了,说明队列执行完了
并且页面并非等待邮件发完才跳转,而是发送这个队列命令后直接重定向到了user列表页面(跳转很快),这就是异步队列的整个工做流程
固然若是你看了我以前的一片文章也能够作作全局SQL监听,你就会在日志中发现,每执行一个队列 job表里面就要执行4次命令增、删、改、查
,若是是10000条数据的队列就是40000次的表操做,因此说database的消息队列用也得小心,虽然是异步的,考虑的因素仍是比较多的。
这个消息队列,说实话丢丢哥我也是用得少,为何呢?暂时并无发现它的应用场景的优点。
与异步不一样的是设置同步消息队列 将.env
或config/queue.php
里面的配置改为是 sync
而后执行页面的时候发现页面等待跳转的时间很长,得全部的邮件发送完成后才会跳转页面(若是队列中有任务执行失败反复的参试 那这页面应该确定timeout了)
1.队列有可能失败,失败的队列会写入到mysql
的failed_jobs
表里面:
2.那么如何让这些失败的队列让电脑后面自动去执行消息推送呢?也就是执行这些命令,怎么让程序自动完成
3.若是是在一个服务器中用消息队列,是否是一直要开常驻进程??那是否是有消耗?当异步到达一个程度的时候,是否是能够开服务器集群里面的异步服务器
专门来作这个事??
但愿个人博客对大家有所帮助,你的承认就是我最大的动力。。
https://www.blog8090.com/
本文为做者原创,容许转载,转载后请以连接形式说明文章出处. 如转载但不标明来源,后果自负。