Laravel框架中队列和工作(Queues、Jobs)操作实例详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Laravel框架中队列和工作(Queues、Jobs)操作实例详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8163字,纯文字阅读大概需要12分钟。
内容图文
?更新时间:2020年04月06日 14:51:05 ? 作者:Eagle L. ? ? 这篇文章主要介绍了Laravel框架中队列和工作(Queues、Jobs)操作实例详解,需要的朋友可以参考下
在我们的web应用中,经常会遇到这样的情况:
用户在进行了某项操作后,我们需要在后台完成一个耗时且耗费资源的任务,以对应用户的操作。
通常来说,web应用中的操作都是同步的(synchronous),即用户的操作可以立即得到回馈。
但是在以上情况下,同步等待操作结果将是灾难性的。比如用户点击了申请密码重置邮件,倘若我们让用户一直停滞在等待页面,直至邮件发送成功,那么用户体验将非常地不好,因为有时候可能需要很长的时间才能将邮件发送完成。
从另一个角度来说,如果我们服务器处于高负荷的情况,当多个用户同时请求发送邮件等操作时,我们不希望同时地给服务器增加负荷,否则可能会导致服务器崩溃,造成无法预估的情况。
从以上的讨论可以看出,我们需要一种机制,可以非同步地响应用户操作,并且不会给服务器增加过大的负荷。
那么这样一种机制就是Queues和Jobs(即队列和工作)。
如果你系统地学习过计算机科学,那么队列的概念你应该不陌生。假设我们去银行办事,我们拿了一个号,发现前面有8个人在等待,那么我们实际上就处在一个队列之中,队列中靠前的人会先被叫到号码,并且叫号的顺序即拿号的顺序。这样的队列就叫做Queue,采用的是先到先处理的方式,不允许插队的情况存在。而我们要办的事情就叫Job。
在Laravel中,我们可以很方便地使用Queues及Jobs来达到我们的目的。首先我们需要先来看一下,Laravel中有哪些Queues。
打开config/queue.php,我们可以看到几种常见的队列设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
return [?????
??
?? /*?????
?? |--------------------------------------------------------------------------?????
?? | Default Queue Connection Name?????
?? |--------------------------------------------------------------------------?????
?? |?????
?? | Laravel's queue API supports an assortment of back-ends via a single?????
?? | API, giving you convenient access to each back-end using the same?????
?? | syntax for every one. Here you may define a default connection.?????
?? |?????
?? */
??
?? 'default' => env( 'QUEUE_DRIVER' , 'sync' ),?????
??
?? /*?????
?? |--------------------------------------------------------------------------?????
?? | Queue Connections?????
?? |--------------------------------------------------------------------------?????
?? |?????
?? | Here you may configure the connection information for each server that?????
?? | is used by your application. A default configuration has been added?????
?? | for each back-end shipped with Laravel. You are free to add more.?????
?? |?????
?? | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"?????
?? |?????
?? */
??
?? 'connections' => [?????
??
???? 'sync' => [?????
?????? 'driver' => 'sync' ,?????
???? ],?????
??
???? 'database' => [?????
?????? 'driver' => 'database' ,?????
?????? 'table' => 'jobs' ,?????
?????? 'queue' => 'default' ,?????
?????? 'retry_after' => 90,?????
???? ],?????
??
???? 'beanstalkd' => [?????
?????? 'driver' => 'beanstalkd' ,?????
?????? 'host' => 'localhost' ,?????
?????? 'queue' => 'default' ,?????
?????? 'retry_after' => 90,?????
???? ],?????
??
???? 'sqs' => [?????
?????? 'driver' => 'sqs' ,?????
?????? 'key' => env( 'SQS_KEY' , 'your-public-key' ),?????
?????? 'secret' => env( 'SQS_SECRET' , 'your-secret-key' ),?????
?????? 'prefix' => env( 'SQS_PREFIX' , 'https://sqs.us-east-1.amazonaws.com/your-account-id' ),?????
?????? 'queue' => env( 'SQS_QUEUE' , 'your-queue-name' ),?????
?????? 'region' => env( 'SQS_REGION' , 'us-east-1' ),?????
???? ],?????
??
???? 'redis' => [?????
?????? 'driver' => 'redis' ,?????
?????? 'connection' => 'default' ,?????
?????? 'queue' => 'default' ,?????
?????? 'retry_after' => 90,?????
?????? 'block_for' => null,?????
???? ],?????
??
?? ],?????
??
?? /*?????
?? |--------------------------------------------------------------------------?????
?? | Failed Queue Jobs?????
?? |--------------------------------------------------------------------------?????
?? |?????
?? | These options configure the behavior of failed queue job logging so you?????
?? | can control which database and table are used to store the jobs that?????
?? | have failed. You may change them to any database / table you wish.?????
?? |?????
?? */
??
?? 'failed' => [?????
???? 'database' => env( 'DB_CONNECTION' , 'mysql' ),?????
???? 'table' => 'failed_jobs' ,?????
?? ],?????
??
];
|
在connections中,我们看到sync这个连接。sync是Laravel默认的队列,代表的就是synchronous,即同步队列。
今天我们要来看一下,如何使用database,即数据库来实现异步任务处理。
要使用database来作为队列的内部实现机制,我们需要建立一张用于储存Jobs的表:
1 2 |
$ php artisan queue:table????
$ php artisan migrate
|
以上命令将会在数据库创建名为jobs的表。
队列我们有了,那么现在我们来看一下Jobs。Laravel中jobs文件默认位置在app/Jobs文件夹下,我们可以通过make:job这个Artisan命令快速创建我们的job类:
1 |
$ php artisan make :job SendEmail
|
生成的job会实现Illuminate\Contracts\Queue\ShouldQueue这个接口,表明生成的job对象将被推到队列中进行异步处理。
job类其实很简单,里面只有一个名为handle的方法,该方法在job被queue处理的时候自动被调用。
在上面的命令中,我们创建了一个名为SendEmail的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php???
??
namespace App\Jobs;???
??
use App\Email;???
use Illuminate\Bus\Queueable;???
use Illuminate\Queue\SerializesModels;???
use Illuminate\Queue\InteractsWithQueue;???
use Illuminate\Contracts\Queue\ShouldQueue;???
use Illuminate\Foundation\Bus\Dispatchable;???
??
class SendEmail implements ShouldQueue???
{???
?? use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;???
??
?? protected $email ;???
??
?? /**???
??? * Create a new job instance.???
??? *???
??? * @param Podcast $podcast???
??? * @return void???
??? */
?? public function __construct(Email $email )???
?? {???
???? $this ->email = $email ;???
?? }???
??
?? /**???
??? * Execute the job.???
??? *???
??? * @param AudioProcessor $processor???
??? * @return void???
??? */
?? public function handle()???
?? {???
???? // Process email and send the email to recipient(s)???
???? // 这里我们可以处理我们的邮件并将邮件发送至接收人
?? }???
}
|
可以看到,我们可以将model传递进job的constructor中。Laravel会自动序列化(Serialize)模型的识别信息,在job真正被处理的时候,完整的模型数据才会被从数据库调用出来。另外,在handle方法中,我们也可以注入我们的依赖dependencies。
好了,现在我们有了job类,可以创建job对象了,那么如何把job添加进队列呢?
在我们的控制器中,我们可以调用job的dispatch方法来将其添加进队列中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php?
??
namespace App\Http\Controllers;?
??
use App\Jobs\SendEmail;?
use Illuminate\Http\Request;?
use App\Http\Controllers\Controller;?
use App\Email;
??
class EmailsController extends Controller?
{?
?? /**?
??? * Store a new email.?
??? *?
??? * @param Request $request?
??? * @return Response?
??? */
?? public function send(Request $request )?
?? {?
???? // Create email...?
???? // 这里我们提取email信息并创建$email, Email是我们自定义的Model
???? $email = Email::create( $request ->only( 'sender' , 'to' , 'content' ));
??
???? SendEmail::dispatch( $email );?
?? }?
}
|
这样一来,每当我们的控制器调用send方法时,就会创建一个SendEmail的job在数据库中。
那么怎么样调用Queue Worker来处理我们的jobs呢?
在.env文件中,我们将QUEUE_DRIVER=sync改为QUEUE_DRIVER=database。
接下来,我们运行以下Artisan命令:
1 |
$ php artisan queue:work
|
队列的worker会一直运行,每当有任务被添加进数据库jobs表中,worker便会自动抓取出任务进行处理。当任务失败时,worker会重复执行任务,直至最大尝试次数(默认为255)。我们可以手动设置最大尝试次数:
1 |
$ php artisan queue:work --tries=3
|
当然,我们也可以手动设置任务的超时(默认90s,在config/queue.php中的retry_after设置):
1 |
$ php artisan queue:work --timeout=30
|
最后,当没有任务的时候,我们可以设置一个睡眠时间,当worker在睡眠时间时,将不会处理任务:
1 |
$ php artisan queue:work -- sleep =10
|
上面的命令意思是每当worker处理完所有任务后,会睡眠10s,然后才会再次检查任务队列
本文使用Laravel 5.6进行讲解
本文主要讲解了Laravel框架中队列和工作(Queues、Jobs)操作实例详解,更多关于Laravel框架的使用技巧请查看下面的相关链接
内容总结
以上是互联网集市为您收集整理的Laravel框架中队列和工作(Queues、Jobs)操作实例详解全部内容,希望文章能够帮你解决Laravel框架中队列和工作(Queues、Jobs)操作实例详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。