[ Laravel 5.2 文档 ] 服务 -- 队列
1、简介
Laravel队列服务为各种不同的后台队列提供了统一的API。队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度。
1.1 配置
队列配置文件存放在 config/queue.php。在该文件中你将会找到框架自带的每一个队列驱动的连接配置,包括数据库、 Beanstalkd、 IronMQ、 Amazon SQS、 Redis以及同步(本地使用)驱动。其中还包含了一个null队列驱动以拒绝队列任务。
1.2 队列驱动预备知识
数据库
为了使用 database队列驱动,需要一张数据库表来存放任务,要生成创建该表的迁移,运行Artisan命令 queue:table,迁移被创建好了之后,使用 migrate命令运行迁移:
php artisan queue:tablephp artisan migrate
其它队列依赖
下面是以上列出队列驱动需要安装的依赖:
- Amazon SQS: aws/aws-sdk-php ~3.0
- Beanstalkd: pda/pheanstalk ~3.0
- Redis: predis/predis ~1.0
2、编写任务类
2.1 生成任务类
默认情况下,应用的所有队列任务都存放在 app/Jobs目录。你可以使用Artisan CLI生成新的队列任务:
php artisan make:job SendReminderEmail
该命令将会在 app/Jobs目录下生成一个新的类,并且该类实现了 Illuminate\Contracts\Queue\ShouldQueue接口,告诉Laravel该任务应该被推送到队列而不是同步运行。
2.2 任务类结构
任务类非常简单,正常情况下只包含一个当队列处理该任务时被执行的 handle方法,让我们看一个任务类的例子:
<?phpnamespace App\Jobs;use App\User;use App\Jobs\Job;use Illuminate\Contracts\Mail\Mailer;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;class SendReminderEmail extends Job implements ShouldQueue{ use InteractsWithQueue, SerializesModels; protected $user; /** * 创建一个新的任务实例 * * @param User $user * @return void */ public function __construct(User $user) { $this->user = $user; } /** * 执行任务 * * @param Mailer $mailer * @return void */ public function handle(Mailer $mailer) { $mailer->send('emails.reminder', ['user' => $this->user], function ($m) { // }); $this->user->reminders()->create(...); }}
在本例中,注意我们能够直接将Eloquent模型传递到对列任务的构造函数中。由于该任务使用了 SerializesModelstrait,Eloquent模型将会在任务被执行是优雅地序列化和反序列化。如果你的队列任务在构造函数中接收Eloquent模型,只有模型的主键会被序列化到队列,当任务真正被执行的时候,队列系统会自动从数据库中获取整个模型实例。这对应用而言是完全透明的,从而避免序列化整个Eloquent模型实例引起的问题。
handle方法在任务被队列处理的时候被调用,注意我们可以在任务的 handle方法中进行依赖注入。Laravel服务容器会自动注入这些依赖。
出错
如果任务被处理的时候抛出异常,则该任务将会被自动释放回队列以便再次尝试执行。任务会持续被释放知道尝试次数达到应用允许的最大次数。最大尝试次数通过Artisan任务 queue:listen或 queue:work上的 --tries开关来定义。关于运行队列监听器的更多信息可以在下面看到。
手动释放任务
如果你想要手动释放任务,生成的任务类中自带的 InteractsWithQueuetrait提供了释放队列任务的 release方法,该方法接收一个参数——同一个任务两次运行之间的等待时间:
public function handle(Mailer $mailer){ if (condition) { $this->release(10); }}
检查尝试运行次数
正如上面提到的,如果在任务处理期间发生异常,任务会自动释放回队列中,你可以通过 attempts方法来检查该任务已经尝试运行次数:
public function handle(Mailer $mailer){ if ($this->attempts() > 3) { // }}
3、推送任务到队列
默认的 Laravel 控制器位于 app/Http/Controllers/Controller.php并使用了 DispatchesJobstrait。该trait提供了一些允许你方便推送任务到队列的方法,例如 dispatch方法:
<?phpnamespace App\Http\Controllers;use App\User;use Illuminate\Http\Request;use App\Jobs\SendReminderEmail;use App\Http\Controllers\Controller;class UserController extends Controller{ /** * 发送提醒邮件到指定用户 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $this->dispatch(new SendReminderEmail($user)); }}
DispatchesJobs Trait
当然,有时候你想要从应用中路由或控制器之外的某些地方分发任务,因为这个原因,你可以在应用的任何类中包含 DispatchesJobstrait,从而获取对分发方法的访问,举个例子,下面是使用该trait的示例类:
<?phpnamespace App;use Illuminate\Foundation\Bus\DispatchesJobs;class ExampleClass{ use DispatchesJobs;}
dispatch方法
或者,你也可以使用全局的dispatch方法:
Route::get('/job', function () { dispatch(new App\Jobs\PerformTask); return 'Done!';});
为任务指定队列
你还可以指定任务被发送到的队列。
根据任务被推送到的不同队列,你可以对队列任务进行“分类”,甚至优先考虑分配给多个队列的worker数目。这并不会如队列配置文件中定义的那样将任务推送到不同队列“连接”,而只是在单个连接中发送给特定队列。要指定该队列,使用任务实例上的 onQueue方法,该方法由 Laravel 自带的基类 App\Jobs\Job中的 Illuminate\Bus\Queueabletrait提供:
<?phpnamespace App\Http\Controllers;use App\User;use Illuminate\Http\Request;use App\Jobs\SendReminderEmail;use App\Http\Controllers\Controller;class UserController extends Controller{ /** * 发送提醒邮件到指定用户 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $job = (new SendReminderEmail($user))->onQueue('emails'); $this->dispatch($job); }}
3.1 延迟任务
有时候你可能想要延迟队列任务的执行。例如,你可能想要将一个注册15分钟后给消费者发送提醒邮件的任务放到队列中,可以通过使用任务类上的 delay方法来实现,该方法由 Illuminate\Bus\Queueabletrait提供:
<?phpnamespace App\Http\Controllers;use App\User;use Illuminate\Http\Request;use App\Jobs\SendReminderEmail;use App\Http\Controllers\Controller;class UserController extends Controller{ /** * 发送提醒邮件到指定用户 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $job = (new SendReminderEmail($user))->delay(60); $this->dispatch($job); }}
在本例中,我们指定任务在队列中开始执行前延迟60秒。
注意:Amazon SQS服务最大延迟时间是15分钟。
3.2 任务事件
任务完成事件
Queue::after方法允许你在队列任务执行成功后注册一个要执行的回调函数。在该回调中我们可以添加日志、统计数据。例如,我们可以在Laravel内置的 AppServiceProvider中添加事件回调:
<?phpnamespace App\Providers;use Queue;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ /** * Bootstrap any application services. * * @return void */ public function boot() { Queue::after(function ($connection, $job, $data) { // }); } /** * Register the service provider. * * @return void */ public function register() { // }}
4、运行队列监听器
启动任务监听器
Laravel 包含了一个 Artisan 命令用来运行被推送到队列的新任务。你可以使用 queue:listen命令运行监听器:
php artisan queue:listen
还可以指定监听器使用哪个队列连接:
php artisan queue:listen connection
注意一旦任务开始后,将会持续运行直到手动停止。你可以使用一个过程监视器如Supervisor来确保队列监听器没有停止运行。
队列 优先级
你可以传递逗号分隔的队列连接列表到 listen任务来设置队列优先级:
php artisan queue:listen --queue=high,low
在本例中, high队列上的任务总是在从 low队列移动任务之前被处理。
指定任务超时参数
你还可以设置每个任务允许运行的最大时间(以秒为单位):
php artisan queue:listen --timeout=60
指定队列睡眠时间
此外,可以指定轮询新任务之前的等待时间(以秒为单位):
php artisan queue:listen --sleep=5
需要注意的是队列只会在队列上没有任务时“睡眠”,如果存在多个有效任务,该队列会持续运行,从不睡眠。
4.1 Supervisor配置
Supervisor为Linux操作系统提供的进程监视器,将会在失败时自动重启 queue:listen或 queue:work命令,要在Ubuntu上安装Supervisor,使用如下命令:
sudo apt-get install supervisor
Supervisor配置文件通常存放在 /etc/supervisor/conf.d目录,在该目录中,可以创建多个配置文件指示Supervisor如何监视进程,例如,让我们创建一个开启并监视 queue:work进程的 laravel-worker.conf文件:
[program:laravel-worker]process_name=%(program_name)s_%(process_num)02dcommand=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemonautostart=trueautorestart=trueuser=forgenumprocs=8redirect_stderr=truestdout_logfile=/home/forge/app.com/worker.log
在本例中, numprocs指令让Supervisor运行8个 queue:work进程并监视它们,如果失败的话自动重启。配置文件创建好了之后,可以使用如下命令更新Supervisor配置并开启进程:
sudo supervisord -c /etc/supervisord.confsudo supervisorctl -c /etc/supervisor/supervisord.confsudo supervisorctl rereadsudo supervisorctl updatesudo supervisorctl start laravel-worker:*
要了解更多关于Supervisor的使用和配置,查看 Supervisor文档。此外,还可以使用Laravel Forge从web接口方便地自动配置和管理Supervisor配置。
4.2 后台队列监听器
Artisan命令 queue:work包含一个 --daemon选项来强制队列worker持续处理任务而不必重新启动框架。相较于 queue:listen命令该命令对CPU的使用有明显降低:
php artisan queue:work connection --daemonphp artisan queue:work connection --daemon --sleep=3php artisan queue:work connection --daemon --sleep=3 --tries=3
正如你所看到的, queue:work任务支持大多数 queue:listen中有效的选项。你可以使用 php artisan help queue:work任务来查看所有有效选项。
后台队列监听器编码考虑
后台队列worker在处理每个任务时不重启框架,因此,你要在任务完成之前释放资源,举个例子,如果你在使用GD库操作图片,那么就在完成时使用 imagedestroy释放内存。
类似的,数据库连接应该在后台长时间运行完成后断开,你可以使用 DB::reconnect方法确保获取了一个新的连接。
4.3 部署后台队列监听器
由于后台队列worker是常驻进程,不重启的话不会应用代码中的更改,所以,最简单的部署后台队列worker的方式是使用部署脚本重启所有worker,你可以通过在部署脚本中包含如下命令重启所有worker:
php artisan queue:restart
该命令会告诉所有队列worker在完成当前任务处理后重启以便没有任务被遗漏。
注意:这个命令依赖于缓存系统重启进度表,默认情况下,APC在CLI任务中无法正常工作,如果你在使用APC,需要在APC配置中添加 apc.enable_cli=1。
5、处理失败任务
由于事情并不总是按照计划发展,有时候你的队列任务会失败。别担心,它发生在我们大多数人身上!Laravel包含了一个方便的方式来指定任务最大尝试执行次数,任务执行次数达到最大限制后,会被插入到 failed_jobs表,失败任务的名字可以通过配置文件 config/queue.php来配置。
要创建一个 failed_jobs表的迁移,可以使用 queue:failed-table命令:
php artisan queue:failed-table
运行队列监听器的时候,可以在 queue:listen命令上使用 --tries开关来指定任务最大可尝试执行次数:
php artisan queue:listen connection-name --tries=3
5.1 失败任务事件
如果你想要注册一个队列任务失败时被调用的事件,可以使用 Queue::failing方法,该事件通过邮件或 HipChat通知团队。举个例子,我么可以在Laravel自带的 AppServiceProvider中附件一个回调到该事件:
<?phpnamespace App\Providers;use Queue;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ /** * 启动应用服务 * * @return void */ public function boot() { Queue::failing(function ($connection, $job, $data) { // Notify team of failing job... }); } /** * 注册服务提供者 * * @return void */ public function register() { // }}
任务类的失败方法
想要更加细粒度的控制,可以在队列任务类上直接定义 failed方法,从而允许你在失败发生时执行指定动作:
<?phpnamespace App\Jobs;use App\Jobs\Job;use Illuminate\Contracts\Mail\Mailer;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Bus\SelfHandling;use Illuminate\Contracts\Queue\ShouldQueue;class SendReminderEmail extends Job implements SelfHandling, ShouldQueue{ use InteractsWithQueue, SerializesModels; /** * 执行任务 * * @param Mailer $mailer * @return void */ public function handle(Mailer $mailer) { // } /** * 处理失败任务 * * @return void */ public function failed() { // Called when the job is failing... }}
5.2 重试失败任务
要查看已插入到 failed_jobs数据表中的所有失败任务,可以使用Artisan命令 queue:failed:
php artisan queue:failed
该命令将会列出任务ID,连接,对列和失败时间,任务ID可用于重试失败任务,例如,要重试一个ID为5的失败任务,要用到下面的命令:
php artisan queue:retry 5
要重试所有失败任务,使用如下命令即可:
php artisan queue:retry all
如果你要删除一个失败任务,可以使用 queue:forget命令:
php artisan queue:forget 5
要删除所有失败任务,可以使用 queue:flush命令:
php artisan queue:flush

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> 'Hello World', 'github.com'=> [ 'foo'=> 'bar'], 'forge.laravel.com'=>

Alipay PHP ...

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

이 기사에서는 프레임 워크에 사용자 정의 기능 추가, 아키텍처 이해, 확장 지점 식별 및 통합 및 디버깅을위한 모범 사례에 중점을 둡니다.

기사는 입력 유효성 검사, 인증 및 정기 업데이트를 포함한 취약점을 방지하기 위해 프레임 워크의 필수 보안 기능을 논의합니다.
