- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章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框架的使用技巧请查看下面的相关链接 。
原文链接:https://blog.sbot.io/articles/24 。
最后此篇关于Laravel框架中队列和工作(Queues、Jobs)操作实例详解的文章就讲到这里了,如果你想了解更多关于Laravel框架中队列和工作(Queues、Jobs)操作实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
var urlsearch = "http://192.168.10.113:8080/collective-intellegence/StoreClicks?userid=" + userId +
我有一个非常奇怪的问题,过去两天一直让我抓狂。 我有一个我试图控制的串行设备(LS 100 光度计)。使用设置了正确参数的终端(白蚁),我可以发送命令(“MES”),然后是定界符(CR LF),然后我
我目前正试图让无需注册的 COM 使用 Excel 作为客户端,使用 .NET dll 作为服务器。目前,我只是试图让概念验证工作,但遇到了麻烦。 显然,当我使用 Excel 时,我不能简单地使用与可
我开发了简单的 REST API - https://github.com/pavelpetrcz/MandaysFigu - 我的问题是在本地主机上,WildFly 16 服务器的应用程序运行正常。
我遇到了奇怪的情况 - 从 Django shell 创建一些 Mongoengine 对象是成功的,但是从 Django View 创建相同的对象看起来成功,但 MongoDB 中没有出现任何数据。
我是 flask 的新手,只编写了一个相当简单的网络应用程序——没有数据库,只是一个航类搜索 API 的前端。一切正常,但为了提高我的技能,我正在尝试使用应用程序工厂和蓝图重构我的代码。让它与 pus
我的谷歌分析 JavaScript 事件在开发者控制台中运行得很好。 但是当从外部 js 文件包含在页面上时,它们根本不起作用。由于某种原因。 例如; 下面的内容将在包含在控制台中时运行。但当包含在单
这是一本名为“Node.js 8 the Right Way”的书中的任务。你可以在下面看到它: 这是我的解决方案: 'use strict'; const zmq = require('zeromq
我正在阅读文本行,并创建其独特单词的列表(在将它们小写之后)。我可以使它与 flatMap 一起工作,但不能使它与 map 的“子”流一起工作。 flatMap 看起来更简洁和“更好”,但为什么 di
我正在编写一些 PowerShell 脚本来进行一些构建自动化。我发现 here echo $? 根据前面的语句返回真或假。我刚刚发现 echo 是 Write-Output 的别名。 写主机 $?
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我将一个工作 View Controller 类从另一个项目复制到一个新项目中。我无法在新项目中加载 View 。在旧项目中我使用了presentModalViewController。在新版本中,我
我对 javascript 很陌生,所以很难看出我哪里出错了。由于某种原因,我的功能无法正常工作。任何帮助,将不胜感激。我尝试在外部 js 文件、头部/主体中使用它们,但似乎没有任何效果。错误要么出在
我正在尝试学习Flutter中的复选框。 问题是,当我想在Scaffold(body :)中使用复选框时,它正在工作。但我想在不同的地方使用它,例如ListView中的项目。 return Cente
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我有一个组合框,其中包含一个项目,比如“a”。我想调用该组合框的 Action 监听器,仅在手动选择项目“a”完成时才调用。我也尝试过 ItemStateChanged,但它的工作原理与 Action
你能看一下照片吗?现在,一步前我执行了 this.interrupt()。您可以看到 this.isInterrupted() 为 false。我仔细观察——“这个”没有改变。它具有相同的 ID (1
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我正在尝试在我的网站上设置一个联系表单,当有人点击发送时,就会运行一个作业,并在该作业中向所有管理员用户发送通知。不过,我在失败的工作表中不断收到此错误: Illuminate\Database\El
我是一名优秀的程序员,十分优秀!