대기줄
ㅋㅋ
- Database
- 기타 대기열 기반 종속성 확장 패키지
- 작업 생성
- 작업 클래스 생성
- 작업 클래스 구조
- 작업 배포
- 지연된 배포 작업 체인 연결 및 대기열
- 작업을 지정된 대기열에 배포
- 작업을 지정된 연결에 배포
- 최대 시도 횟수 빈도 제한
- 오류 처리
- 큐 우선 순위
- 대기열 폐쇄
- exeue 큐 프로세서 실행
- 연결 및 큐를 지정합니다. 단일 작업을 실행하여 모든 대기열의 작업을 처리 한 다음 자원 예방 조치를 종료합니다. 시간 초과
- 작업 만료
- 프로세서 시간 초과
- 큐 프로세스 절전 시간
- 감독자 구성
- 감독자 설치
- 실패한 작업 후 정리
- 미션 이벤트
Queue
소개
{tip} 이제 Laravel은 Redis 대기열을 위한 아름다운 대시보드 및 구성 시스템인 Horizon을 제공합니다. 자세한 내용은 전체 Horizon 설명서를 확인하세요.
Laravel 대기열은 Beanstalk, Amazon SQS, Redis 및 관계형 데이터베이스 기반의 다른 대기열과 같은 다양한 백엔드 대기열 서비스에 대한 통합 API를 제공합니다. 대기열의 목적은 이메일 전송과 같이 시간이 많이 걸리는 작업의 처리를 지연시켜 웹 요청 및 응답 시간을 크게 단축하는 것입니다.
큐 구성 파일은
, Redisconfig/queue.php
파일에 저장됩니다. 데이터베이스 Beanstalkdconfig/queue.php
文件中。每一种队列驱动的配置都可以在该文件中找到,包括数据库, Beanstalkd, Amazon SQS, Redis,以及同步(本地使用)驱动。其中还包含了一个null
, Amazon SQS및 동기식(로컬 사용) 드라이버. 또한 대기열을 중단하는 작업을 위한
🎜🎜null
대기열 드라이버도 포함되어 있습니다.Connection Vs. Queue
Laravel 큐를 사용하기 전에 "연결"과 "큐"의 차이점을 이해하는 것이 중요합니다.
config/queue.php
구성 파일에는connections
구성 옵션이 있습니다. 이 옵션은 Amazon SQS, Beanstalk 또는 Redis와 같은 백엔드 서비스에 대한 고유한 연결을 정의합니다. 어느 쪽이든 특정 연결에 대해 여러 개의 "대기열"이 있을 수 있으며 "대기열"은 서로 다른 스택 또는 대기열에 있는 많은 수의 작업으로 간주될 수 있습니다.config/queue.php
配置文件里,有一个connections
配置选项。这个选项给 Amazon SQS,Beanstalk,或者 Redis 这样的后端服务定义了一个特有的连接。不管是哪一种,一个给定的连接可能会有多个 「队列」,而 「队列」 可以被认为是不同的栈或者大量的队列任务。要注意的是,
queue
配置文件中每个连接的配置示例中都包含一个queue
属性。这是默认队列任务被发给指定连接的时候会被分发到这个队列中。换句话说,如果你分发任务的时候没有显式定义队列,那么它就会被放到连接配置中queue
属性所定义的队列中:// 这个任务将被分发到默认队列... Job::dispatch(); // 这个任务将被发送到「emails」队列... Job::dispatch()->onQueue('emails');
有些应用可能不需要把任务发到不同的队列,而只发到一个简单的队列中就行了。但是把任务推到不同的队列仍然是非常有用的,因为 Laravel 队列处理器允许你定义队列的优先级,所以你能给不同的队列划分不同的优先级或者区分不同任务的不同处理方式了。比如说,如果你把任务推到
high
队列中,你就能让队列处理器优先处理这些任务了:php artisan queue:work --queue=high,default
驱动的必要设置
Database
为了使用
database
队列驱动,你需要一张数据表来存储任务。运行queue:table
Artisan 命令来创建这张表的迁移文件。当迁移文件创建好后,你就可以使用migrate
命令来进行迁移:php artisan queue:table php artisan migrate
Redis
为了使用
redis
队列驱动,你需要在config/database.php
配置文件中配置 Redis 的数据库连接。Redis 集群
如果你的 Redis 队列驱动使用了 Redis 集群,你的队列名必须包含一个 key hash tag 。这是为了确保所有的 Redis 键对于一个队列都被放在同一哈希中。
'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => '{default}', 'retry_after' => 90, ],
阻塞
当使用 Redis 队列时,你可以用
block_for
配置项来具体说明驱动应该在将任务重新放入 Redis 数据库以及处理器轮询之前阻塞多久。基于你的队列加载来调整这个值比把新任务放入 Redis 数据库轮询要更有效率的多。例如,你可以将这个值设置为
5
queue
구성 파일의 각 연결 구성 예에는queue
속성이 포함되어 있다는 점에 유의하세요. 이는 지정된 연결로 전송될 때 이 대기열에 배포되는 기본 대기열 작업입니다. 즉, 작업을 배포할 때 대기열을 명시적으로 정의하지 않으면 연결 구성의queue
속성으로 정의된 대기열에 배치됩니다.일부 애플리케이션에서는 그럴 필요가 없을 수도 있습니다. 작업은 다른 대기열로 전송되지만 단순 대기열로만 전송됩니다. 그러나 작업을 다른 큐에 푸시하는 것은 여전히 매우 유용합니다. Laravel 큐 핸들러를 사용하면 큐의 우선순위를 정의할 수 있으므로 다른 큐에 다른 우선순위를 할당하거나 다른 작업에 대해 다른 처리 방법을 구별할 수 있습니다. 예를 들어 작업을'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'retry_after' => 90, 'block_for' => 5, ],
high
대기열에 푸시하면 대기열 프로세서가 다음 작업의 우선 순위를 지정하도록 할 수 있습니다. 🎜php artisan make:job ProcessPodcast
🎜 🎜🎜🎜드라이버에 필요한 설정🎜🎜데이터베이스
🎜를 사용하려면 < code>database 큐 드라이버를 사용하려면 작업을 저장하기 위한 데이터 테이블이 필요합니다.queue:table
Artisan 명령어를 실행하여 이 테이블에 대한 마이그레이션 파일을 생성하세요. 마이그레이션 파일이 생성된 후migration
명령을 사용하여 마이그레이션할 수 있습니다: 🎜<?php namespace App\Jobs; use App\Podcast; use App\AudioProcessor; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; class ProcessPodcast implements ShouldQueue{ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $podcast; /** * 创建一个新的任务实例。 * * @param Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * 运行任务。 * * @param AudioProcessor $processor * @return void */ public function handle(AudioProcessor $processor) { // Process uploaded podcast... } }
🎜Redis
🎜redis
큐 드라이버를 사용하려면config/database.php
구성 파일에서 Redis 데이터베이스 연결을 구성해야 합니다. 🎜🎜Redis 클러스터🎜🎜Redis 대기열 드라이버가 Redis 클러스터를 사용하는 경우 대기열 이름에 키 해시 태그 . 이는 대기열의 모든 Redis 키가 동일한 해시에 배치되도록 하기 위한 것입니다. 🎜use App\Jobs\ProcessPodcast; $this->app->bindMethod(ProcessPodcast::class.'@handle', function ($job, $app) { return $job->handle($app->make(AudioProcessor::class)); });
🎜차단🎜🎜Redis 대기열을 사용할 때block_for
구성 항목을 사용하여 드라이버가 작업을 Redis 데이터베이스에 다시 입력하고 폴링하도록 지정할 수 있습니다. 프로세서 이전에 얼마나 오랫동안 차단되었습니까? 🎜🎜큐 로드에 따라 이 값을 조정하는 것이 Redis 데이터베이스에 새 작업을 추가하고 폴링하는 것보다 훨씬 효율적입니다. 예를 들어 이 값을5
로 설정하면 드라이버가 작업을 사용할 수 있을 때까지 기다리는 동안 5초 동안 차단해야 함을 나타낼 수 있습니다. 🎜rreee🎜🎜기타 대기열 드라이버 종속성 확장 패키지
목록의 대기열 서비스를 사용하기 전에 다음 종속성 확장 패키지를 설치해야 합니다.
- Amazon SQS:
aws/aws-sdk-php ~3.0
< /li>aws/aws-sdk-php ~3.0
- Beanstalkd:
pda/pheanstalk ~4.0
- Redis:
predis/predis ~1.0
创建任务
生成任务类
在你的应用程序中,队列的任务类都默认放在
app/Jobs
目录下。如果这个目录不存在,那当你运行make:job
Artisan 命令时目录就会被自动创建。你可以用以下的 Artisan 命令来生成一个新的队列任务:<?php namespace App\Http\Controllers; use App\Jobs\ProcessPodcast; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PodcastController extends Controller{ /** * 存储一个新的播客节目。 * * @param Request $request * @return Response */ public function store(Request $request) { // 创建播客... ProcessPodcast::dispatch($podcast); } }
生成的类实现了
IlluminateContractsQueueShouldQueue
接口,这意味着这个任务将会被推送到队列中,而不是同步执行。任务类结构
任务类的结构很简单,一般来说只会包含一个让队列用来调用此任务的
handle
方法。我们来看一个示例的任务类。这个示例里,假设我们管理着一个播客发布服务,在发布之前需要处理上传播客文件:<?php namespace App\Http\Controllers; use App\Jobs\ProcessPodcast; use Illuminate\Http\Request; use App\Http\Controllers\Controller;class PodcastController extends Controller{ /** * 存储一个新的播客节目。 * * @param Request $request * @return Response */ public function store(Request $request) { // 创建播客... ProcessPodcast::dispatch($podcast) ->delay(now()->addMinutes(10)); } }
注意,在这个例子中,我们在任务类的构造器中直接传递了一个 Eloquent 模型 。因为我们在任务类里引用了
SerializesModels
这个 trait,使得 Eloquent 模型在处理任务时可以被优雅地序列化和反序列化。如果你的队列任务类在构造器中接收了一个 Eloquent 模型,那么只有可识别出该模型的属性会被序列化到队列里。当任务被实际运行时,队列系统便会自动从数据库中重新取回完整的模型。这整个过程对你的应用程序来说是完全透明的,这样可以避免在序列化完整的 Eloquent 模式实例时所带来的一些问题。在队列处理任务时,会调用
handle
方法,而这里我们也可以通过handle
方法的参数类型提示,让 Laravel 的 服务容器 自动注入依赖对象。如果你想完全控制容器如何将依赖对象注入至
handle
方法,可以使用容器的bindMethod
方法。bindMethod
方法接受一个任务和容器的回调。虽然可以直接在回调中可以调用handle
方法,但建议应该从 service provider 调用为佳:<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Jobs\ProcessPodcast; use App\Http\Controllers\Controller; class PodcastController extends Controller{ /** * Store a new podcast. * * @param Request $request * @return Response */ public function store(Request $request) { // Create podcast... ProcessPodcast::dispatchNow($podcast); } }
{note} 像图片内容这种二进制数据,在放入队列任务之前必须使用
Redis:base64_encode
Beanstalkd:pda/pheanstalk ~4.0
predis/predis ~1.0
작업 생성
🎜 < div name="17bfa2" data-unique="17bfa2">🎜작업 클래스 생성
🎜애플리케이션에서 대기열의 작업 클래스는app/Jobs
디렉토리. 이 디렉터리가 존재하지 않으면make:job
Artisan 명령을 실행할 때 자동으로 생성됩니다. 다음 Artisan 명령어를 사용하여 새 대기열 작업을 생성할 수 있습니다: 🎜ProcessPodcast::withChain([ new OptimizePodcast, new ReleasePodcast ])->dispatch();
🎜생성된 클래스는IlluminateContractsQueueShouldQueue
인터페이스를 구현합니다. 이는 작업이 동기적으로 실행되기보다는 대기열에 푸시된다는 의미입니다. 🎜🎜🎜🎜🎜태스크 클래스 구조
🎜태스크 클래스 구조는 매우 간단합니다. 일반적으로 대기열이 이 작업을 호출하는 데 사용하는handle
메서드만 포함한다고 말합니다. 예제 작업 클래스를 살펴보겠습니다. 이 예에서는 팟캐스트 게시 서비스를 관리하고 게시하기 전에 업로드된 팟캐스트 파일을 처리해야 한다고 가정합니다. 🎜ProcessPodcast::withChain([ new OptimizePodcast, new ReleasePodcast ])->dispatch()->allOnConnection('redis')->allOnQueue('podcasts');
🎜 이 예에서는 작업 클래스의 생성자에 직접 Eloquent 모델을 전달합니다. 작업 클래스에서SerializesModels
특성을 참조했기 때문에 Eloquent 모델은 작업을 처리할 때 정상적으로 직렬화 및 역직렬화될 수 있습니다. 대기열 작업 클래스가 생성자에서 Eloquent 모델을 받으면 해당 모델을 인식하는 속성만 대기열에 직렬화됩니다. 작업이 실제로 실행되면 대기열 시스템은 데이터베이스에서 전체 모델을 자동으로 검색합니다. 이 전체 프로세스는 애플리케이션에 완전히 투명하므로 전체 Eloquent 패턴 인스턴스 직렬화와 관련된 일부 문제를 피할 수 있습니다. 🎜🎜큐가 작업을 처리할 때handle
메서드가 호출되며 여기서handle
메서드의 매개변수 유형 힌트를 사용하여 Laravel의 서비스 컨테이너가 자동으로 주입하도록 할 수도 있습니다. 종속 개체. 🎜🎜컨테이너가 종속 개체를handle
메서드에 삽입하는 방법을 완전히 제어하려면 컨테이너의bindMethod
메서드를 사용할 수 있습니다.bindMethod
메서드는 작업 및 컨테이너 콜백을 허용합니다.handle
메소드는 콜백에서 직접 호출할 수도 있지만 서비스 제공자로부터 호출하는 것을 권장합니다. 🎜<?php namespace App\Http\Controllers; use App\Jobs\ProcessPodcast; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PodcastController extends Controller{ /** * 存储一个新的播客节目。 * * @param Request $request * @return Response */ public function store(Request $request) { // 创建播客... ProcessPodcast::dispatch($podcast)->onQueue('processing'); } }
🎜{note} 이미지 콘텐츠와 같은 바이너리 데이터는 대기열 작업을 변환하려면
base64_encode
메서드를 사용해야 합니다. 그렇지 않으면 이 작업이 대기열에 배치될 때 JSON으로 올바르게 직렬화되지 않을 수 있습니다. 🎜🎜🎜🎜🎜🎜🎜🎜작업 배포
작업 클래스 작성을 마친 후에는 자체
dispatch
메서드를 사용하여 배포할 수 있습니다.dispatch
메소드에 전달된 매개변수는 작업 생성자에 전달됩니다:dispatch
方法分发它。传递给dispatch
方法的参数将会被传递给任务的构造函数:<?php namespace App\Http\Controllers; use App\Jobs\ProcessPodcast; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PodcastController extends Controller{ /** * 存储一个新播客节目。 * * @param Request $request * @return Response */ public function store(Request $request) { // 创建播客... ProcessPodcast::dispatch($podcast)->onConnection('sqs'); } }
延迟分发
如果你想延迟你的队列任务的执行,你可以在分发任务的时候使用
delay
方法。例如,让我们详细说明一个十分钟之后才会执行的任务:ProcessPodcast::dispatch($podcast) ->onConnection('sqs') ->onQueue('processing');
{note} Amazon SQS 队列服务最大延迟 15 分钟的时间。
同步调度
如果您想立即(同步)执行队列任务,可以使用
dispatchNow
方法。 使用此方法时,队列任务将不会排队,并立即在当前进程中运行:php artisan queue:work --tries=3
工作链
工作链允许你具体定义一个按序列执行队列任务的列表。一旦序列中的任务失败了,剩余的工作将不会执行。要运行一个工作链,你可以对可分发的任务使用
withChain
方法:<?phpnamespace App\Jobs;class ProcessPodcast implements ShouldQueue{ /** * 任务可以尝试的最大次数。 * * @var int */ public $tries = 5;}
{note} 使用
$this->delete()
方法删除队列任务不会阻止工作链任务执行。只有当工作链中的任务执行失败时,工作链才会停止执行。工作链连接 & 队列
如果你想定义用于工作链的默认连接和队列,你可以使用
allOnConnection
和allOnQueue
方法。 这些方法指定了所需队列的连接和队列 —— 除非队列任务被明确指定给了不同的连接 / 队列:/** * 定义任务超时时间 * * @return \DateTime */ public function retryUntil(){ return now()->addSeconds(5); }
自定义连接 & 队列
分发任务到指定队列
通过将任务分发到不同队列,你可以将你的队列任务「分类」,甚至指定给不同队列分配的任务数量。记住,这不是推送任务到你定义的队列配置文件的不同的连接里,而是一个单一的连接。要指定队列,在分发任务时使用
onQueue
方法:php artisan queue:work --timeout=30
分发任务到指定连接
如果你在多队列连接中工作,你可以指定将任务分发到哪个连接。要指定连接,在分发任务时使用
onConnection
方法:<?php namespace App\Jobs;class ProcessPodcast implements ShouldQueue{ /** * 任务可以执行的最大秒数 (超时时间)。 * * @var int */ public $timeout = 120;}
当然,你可以链式调用
onConnection
和onQueue
Redis::throttle('key')->allow(10)->every(60)->then(function () { // 任务逻辑... }, function () { // 无法获得锁... return $this->release(10); });
지연된 배포
큐 작업의 실행을 지연하려면 작업을 배포할 때delay
메서드를 사용할 수 있습니다. 예를 들어 10분 동안 실행되지 않는 작업을 자세히 설명하겠습니다.{note} Amazon SQS 대기열 서비스의 최대 지연 시간은 15분입니다. 🎜🎜🎜🎜Redis::funnel('key')->limit(1)->then(function () { // 任务逻辑...}, function () { // 无法获得锁... return $this->release(10); });
🎜동기 디스패칭
🎜원하는 경우(동기적으로 ) 대기열 작업을 실행하려면dispatchNow
메서드를 사용할 수 있습니다. 이 방법을 사용하면 대기 중인 작업이 대기열에 추가되지 않고 현재 프로세스에서 즉시 실행됩니다. 🎜$podcast = App\Podcast::find(1); dispatch(function () use ($podcast) { $podcast->publish(); });
🎜🎜🎜🎜작업 체인
🎜작업 체인을 사용하면 순서대로 실행되는 대기열 작업 목록을 구체적으로 정의할 수 있습니다. 시퀀스의 작업이 실패하면 나머지 작업은 실행되지 않습니다. 작업 체인을 실행하려면 배포 가능한 작업에withChain
메서드를 사용할 수 있습니다. 🎜php artisan queue:work
🎜{note}
$this->delete()
메서드를 사용하세요. 대기열 작업을 삭제해도 작업 체인 작업이 실행되는 데 방해가 되지 않습니다. 작업 체인의 작업이 실행되지 않는 경우에만 작업 체인 실행이 중지됩니다. 🎜🎜작업 체인 연결 및 대기열
🎜작업 체인에 대한 기본 연결 및 대기열을 정의하려면 < code>allOnConnection 및allOnQueue
메서드. 이러한 방법은 원하는 대기열의 연결 및 대기열을 지정합니다. 대기열 작업이 명시적으로 다른 연결/대기열에 할당되지 않는 한: 🎜php artisan queue:work redis
🎜🎜🎜🎜맞춤형 연결 및 대기열
🎜지정된 대기열에 작업 배포 < /h4>🎜작업을 여러 대기열에 분산하면 대기열 작업을 "분류"할 수 있고 여러 대기열에 할당된 작업 수를 지정할 수도 있습니다. 이는 정의한 대기열 구성 파일의 다른 연결로 작업을 푸시하는 것이 아니라 단일 연결로 푸시하는 것임을 기억하세요. 대기열을 지정하려면 작업을 배포할 때
onQueue
메서드를 사용하세요. 🎜php artisan queue:work redis --queue=emails
🎜지정된 연결에 작업 배포
🎜 다중 대기열 연결에서 작업하는 경우 작업을 배포할 연결을 지정할 수 있습니다. 연결을 지정하려면 작업을 디스패치할 때onConnection
메서드를 사용하세요. 🎜php artisan queue:work --once
🎜 물론onConnection
및onQueue
메서드를 연결하여 지정할 수도 있습니다. 연결과 대기열. 🎜php artisan queue:work --stop-when-empty
🎜🎜🎜🎜🎜🎜최대 작업 시도 횟수/시간 초과 값 지정
최대 시도 횟수
작업의 최대 시도 횟수 지정은 Artisan 명령의
--tries
옵션을 통해 지정할 수 있습니다 :--tries
选项 指定:dispatch((new Job)->onQueue('high'));
你可能想通过任务类自身对最大任务尝试次数进行一个更颗粒化的处理。如果最大尝试次数是在任务类中定义的,它将优先于命令行中的值提供:
php artisan queue:work --queue=high,low
基于时间的尝试
作为另外一个选择来定义任务在失败前会尝试多少次,你可以定义一个任务超时时间。这样的话,在给定的时间范围内,任务可以无限次尝试。要定义一个任务的超时时间,在你的任务类中新增一个
retryUntil
方法:php artisan queue:restart
{tip} 你也可以在你的队列事件监听器中使用
retryUntil
方法。超时
{note}
timeout
特性对于 PHP 7.1+ 和pcntl
PHP 扩展进行了优化.同样的,任务执行最大秒数的数值可以通过 Artisan 命令行的
--timeout
php artisan queue:work --timeout=60
원할 수도 있습니다. 최대 작업 시도 횟수에 대한 보다 세부적인 처리는 작업 클래스 자체를 통해 수행됩니다. 최대 시도 횟수가 작업 클래스에 정의된 경우 명령줄의 값보다 우선적으로 제공됩니다:php artisan queue:work --sleep=3
시간 기반 시도실패하기 전에 작업을 시도할 횟수를 정의하는 대신 작업 시간 초과를 정의할 수 있습니다. 이렇게 하면 주어진 시간 내에 작업을 무제한으로 시도할 수 있습니다. 작업 시간 제한을 정의하려면 작업 클래스에retryUntil
메서드를 추가하세요. 🎜sudo apt-get install supervisor
🎜{tip} 대기열 이벤트 리스너의
retryUntil
메서드를 사용할 수도 있습니다. 🎜🎜🎜Timeout🎜🎜{note} PHP 7.1+ 및
🎜마찬가지로 작업 실행의 최대 시간(초) 값은 Artisan 명령줄의pcntl<의
시간 초과
기능 /code> PHP 확장이 최적화되었습니다. 🎜--timeout
옵션을 통해 지정할 수 있습니다. 🎜[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 autostart=true autorestart=true user=forge numprocs=8 redirect_stderr=true stdout_logfile=/home/forge/app.com/worker.log
🎜그러나 작업 클래스 자체에서 시간 초과를 정의할 수도 있습니다. 작업 클래스에 지정된 경우 우선순위는 명령줄(🎜sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:*
🎜🎜🎜🎜🎜🎜)보다 높습니다.Frequency Limiting
{note} 이 기능을 사용하려면 애플리케이션이 Redis 서버를 사용할 수 있어야 합니다.
애플리케이션이 Redis를 사용하는 경우 대기열 작업을 시간이나 동시성에 따라 제한할 수 있습니다. 이 기능은 속도가 제한된 API를 통해 대기열 작업을 사용할 때 유용합니다.
예를 들어
throttle
메서드를 사용하면 특정 유형의 작업이 60초마다 10번만 실행되도록 제한할 수 있습니다. 잠금이 획득되지 않은 경우 일반적으로 나중에 다시 시도할 수 있도록 작업을 대기열에 다시 넣어야 합니다.throttle
方法,你可以限制一个给定类型的任务每 60 秒只执行 10 次。如果没有获得锁,一般情况下你应该将任务放回队列以使其可以被稍后重试。php artisan queue:failed-table php artisan migrate
{tip} 在上述的例子里,
key
可以是任何你想要限制频率的任务类型的唯一识别字符串。例如,使用构件基于任务类名的 key,或它操作的 Eloquent 模型的 ID。{note} 将受限制的作业释放回队列,仍然会增加工作的总数
attempts
。或者,你可以指定一个任务可以同时执行的最大数量。在如下情况时这会很有用处:当一个队列中的任务正在修改资源时,一次只能被一个任务修改。例如,使用
funnel
方法,你可以限制一个给定类型的任务一次只能执行一个处理器:php artisan queue:work redis --tries=3
{tip} 当使用频率限制时,任务执行成功的尝试的次数可能会难以确定。所以,将频率限制与 时间限制 组合是很有作用的。
错误处理
如果在任务执行的时候出现异常,任务会被自动释放到队列中以再次尝试。任务将会一直被释放直到达到应用允许的最大重试次数。最大重试的数值由
queue:work
Artisan 命令的--tries
<?php namespace App\Jobs; use Exception;use App\Podcast; use App\AudioProcessor; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class ProcessPodcast implements ShouldQueue{ use InteractsWithQueue, Queueable, SerializesModels; protected $podcast; /** * 创建任务实例 * * @param Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * 执行任务 * * @param AudioProcessor $processor * @return void */ public function handle(AudioProcessor $processor) { // 上传播客…… } /** * 任务失败的处理过程 * * @param Exception $exception * @return void */ public function failed(Exception $exception) { // 给用户发送任务失败的通知,等等…… } }
{tip} 위의 예에서key
는 빈도를 제한하려는 모든 작업 유형에 대한 고유 식별 문자열이 될 수 있습니다. 예를 들어, 작업 클래스 이름이나 작동하는 Eloquent 모델의 ID를 기반으로 위젯의 키를 사용하세요.{note} 제한된 작업을 대기열로 다시 해제해도
또는 동시에 실행할 수 있는 최대 작업 수를 지정할 수 있습니다. 이는 대기열의 작업이 한 번에 하나의 작업에서만 수정할 수 있는 리소스를 수정할 때 유용할 수 있습니다. 예를 들어,시도
하는 총 작업 수가 늘어납니다.funnel
방법을 사용하면 특정 유형의 작업을 한 번에 하나의 프로세서로만 제한할 수 있습니다.<?php namespace App\Providers; use Illuminate\Support\Facades\Queue; use Illuminate\Queue\Events\JobFailed; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * 启动任意服务。 * * @return void */ public function boot() { Queue::failing(function (JobFailed $event) { // $event->connectionName // $event->job // $event->exception }); } /** * 注册服务提供者。 * * @return void */ public function register() { // } }
{tip} 빈도 제한을 사용하면 성공적인 작업 실행 횟수 시도를 결정하는 것이 어려울 수 있습니다. 따라서 빈도 제한과 시간 제한
을 결합하는 것이 유용합니다.오류 처리작업 실행 중 예외가 발생하면 작업이 자동으로 해제됩니다. 다시 시도하려면 대기열에 있어야 합니다. 애플리케이션에서 허용하는 최대 재시도 횟수에 도달할 때까지 작업이 해제됩니다. 최대 재시도 값은아래🎜에서 확인할 수 있습니다. 🎜🎜🎜🎜🎜🎜🎜🎜Queue Closure🎜🎜작업 클래스를 대기열에 예약하는 대신 직접 클로저를 호출할 수도 있습니다. 이는 수행해야 하는 빠르고 간단한 작업에 유용합니다. 🎜queue:work
Artisan 명령어의--tries
옵션이나 작업 클래스에 의해 정의됩니다. 실행 대기열 처리기에 대한 자세한 내용은php artisan queue:failed
🎜 클로저가 대기열로 전달되면 클로저의 코드 내용이 암호화되어 서명되므로 전송 중에 수정할 수 없습니다. 🎜🎜🎜🎜🎜🎜🎜Run Queue Handler
Laravel에는 대기열에 푸시된 작업을 실행하는 대기열 처리기가 포함되어 있습니다.
queue:work
Artisan 명령을 사용하여 프로세서를 실행할 수 있습니다.queue:work
명령이 실행을 시작하면 수동으로 중지하거나 터미널이 닫힐 때까지 계속 실행됩니다.queue:work
Artisan 命令运行处理器。 注意一旦queue:work
命令开始执行,它会一直运行直到它被手动停止或终端被关闭。php artisan queue:retry 5
{tip} 要使
queue:work
进程一直在后台运行,你应该使用进程管理器比如 Supervisor 来确保队列处理器不会停止运行记住,队列处理器是一个常驻的进程并且在内存中保存着已经启动的应用状态。因此,它们并不会在启动后注意到你代码的更改。所以,在你的重新部署过程中,请记得 重启你的队列处理器.
指定连接 & 队列
你也可以具体说明队列处理器应该使用哪个队列连接。 传递给
work
的连接名应该与你的config/queue.php
配置文件中定义的连接之一相符。php artisan queue:retry all
你甚至可以自定义你的队列处理器使其只执行连接中指定的队列。例如,如果你的所有邮件都由
redis
连接的emails
队列处理,你可以使用如下的命令启动一个仅执行此队列的处理器:php artisan queue:forget 5
执行单一任务
--once
选项用于使队列处理器只处理队列中的单一任务。php artisan queue:flush
处理所有队列的任务然后退出
--stop-when-empty
选项可用于处理队列处理器处理所有作业然后优雅地退出。如果您希望在队列为空后关闭容器,则在 Docker 容器中运行 Laravel 队列时,此选项很有用:/** * 如果模型缺失即删除任务。 * * @var bool */ public $deleteWhenMissingModels = true;
资源注意事项
后台驻留的队列处理器不会在执行完每个任务后「重启」框架。因此,你应该在每个任务完成后释放任何占用过大的资源。例如,如果你正在用 GD 库执行图像处理,你应该在完成后使用
imagedestroy
<?php namespace App\Providers; use Illuminate\Support\Facades\Queue; use Illuminate\Support\ServiceProvider; use Illuminate\Queue\Events\JobProcessed; use Illuminate\Queue\Events\JobProcessing; class AppServiceProvider extends ServiceProvider{ /** * 引导启动任意应用服务。 * * @return void */ public function boot() { Queue::before(function (JobProcessing $event) { // $event->connectionName // $event->job // $event->job->payload() }); Queue::after(function (JobProcessed $event) { // $event->connectionName // $event->job // $event->job->payload() }); } /** * 注册服务提供者。 * * @return void */ public function register() { // } }
{tip}
대기열 프로세서는 상주 프로세스이며 시작된 애플리케이션 상태를 메모리에 유지한다는 점을 기억하세요. 따라서 시작 후 코드 변경 사항을 알 수 없습니다. 따라서 재배포 프로세스 중에 대기열 프로세서를 다시 시작하세요 .queue:work
프로세스를 백그라운드에서 계속 실행하려면 Supervisor연결 및 대기열 지정
🎜 대기열 처리기가 사용해야 하는 대기열 연결을 지정할 수도 있습니다.work
에 전달된 연결 이름은config/queue.php
구성 파일에 정의된 연결 중 하나와 일치해야 합니다. 🎜Queue::looping(function () { while (DB::transactionLevel() > 0) { DB::rollBack(); } });
🎜연결에 지정된 대기열만 실행하도록 대기열 처리기를 사용자 정의할 수도 있습니다. 예를 들어 모든 이메일이redis
에 연결된emails
대기열에 의해 처리되는 경우 다음 명령을 사용하여 이 대기열만 실행하는 프로세서를 시작할 수 있습니다: 🎜rrreee🎜단일 작업 실행
🎜--once
옵션은 대기열 프로세서가 단일 작업만 처리하도록 하는 데 사용됩니다. 대기열. 🎜rrreee🎜대기 중인 모든 작업을 처리한 후 종료
🎜--stop-when-empty
옵션을 사용할 수 있습니다. 사용됨 처리 대기열 처리기는 모든 작업을 처리한 다음 정상적으로 종료됩니다. 이 옵션은 Docker 컨테이너에서 Laravel 대기열을 실행할 때 대기열이 비워진 후 컨테이너를 종료하려는 경우 유용합니다: 🎜rrreee🎜리소스 노트
🎜백그라운드 상주 대기열 프로세서는 각 작업을 실행한 후 프레임워크를 "다시 시작"하지 않습니다. 따라서 각 작업이 완료된 후 과도한 리소스를 해제해야 합니다. 예를 들어, GD 라이브러리로 이미지 처리를 수행하는 경우 작업이 완료되면imagedestroy
를 사용하여 메모리를 해제해야 합니다. 🎜🎜🎜🎜🎜🎜🎜큐 우선순위
때때로 큐 실행의 우선순위를 정하고 싶을 수도 있습니다. 예를 들어,
rrreeeconfig/queue.php
에서는default
redis로 연결된queue
대기열의 우선순위를 설정할 수 있습니다. >이낮습니다
. 그러나 경우에 따라 다음과 같이 작업을높음
대기열에 푸시하고 싶을 수도 있습니다.config/queue.php
中你可以将redis
连接的queue
队列的优先级从default
设置为low
。然而, 偶尔你也想像如下方式将一个任务推送到high
队列:要运行一个处理器来确认
rrreeelow
队列中的任务在全部的high
队列任务完成后才继续执行,你可以传递一个逗号分隔的队列名列表作为work
命令的参数。队列处理器 & 部署
因为队列处理器是常驻进程,他们在重启前不会应用你代码的更改。因此,部署使用队列处理器的应用最简单的方法是在部署进程中重启队列处理器。你可以平滑地重启所有队列处理器通过使用
rrreeequeue:restart
方法:这个命令将会引导所有的队列处理器在完成当前任务后平滑「中止」,这样不会有丢失的任务。由于在执行
queue:restart
后队列处理器将会中止,所以你应该运行一个进程管理器例如 Supervisor 来自动重启队列处理器。{tip} 队列使用 缓存 存储重启信号,所以你应该确定在使用这个功能之前配置好缓存驱动。
任务过期 & 超时
任务过期
在你的
config/queue.php
配置文件中,每个队列连接都定义了一个retry_after
选项。这个选项指定了队列连接在重试一个任务前应该等它执行多久。例如,如果retry_after
的值设置为90
,那么任务在执行了 90 秒后将会被放回队列而不是删除它。一般情况下,你应该将retry_after
的值设置为你认为你的任务可能会执行需要最长时间的值。
rrreee{note} 只有在 Amazon SQS 中不存在
프로세서를 실행하여retry_after
rrreee낮음
대기열에 있는 작업이 전체 대기열에 있는지 확인하려면>high
대기열 작업은 완료된 후에만 실행됩니다. 쉼표로 구분된 대기열 이름 목록을work
명령에 인수로 전달할 수 있습니다.🎜🎜큐 프로세서 및 배포🎜🎜큐 프로세서가 상주하기 때문에 프로세스를 수행하며 다시 시작될 때까지 코드에 변경 사항을 적용하지 않습니다. 따라서 대기열 프로세서를 사용하는 애플리케이션을 배포하는 가장 쉬운 방법은 배포 프로세스 중에 대기열 프로세서를 다시 시작하는 것입니다.queue:restart
메서드를 사용하여 모든 대기열 프로세서를 정상적으로 다시 시작할 수 있습니다. 🎜rrreee🎜이 명령은 모든 대기열 프로세서에 현재 작업을 완료한 후 정상적으로 "중단"하도록 지시하므로 Lost 미션이 발생하지 않습니다. . 큐 핸들러는queue:restart
실행 후 종료되므로 Supervisor와 같은 프로세스 관리자를 실행하여 큐 프로세서를 자동으로 다시 시작해야 합니다. 🎜🎜{tip} 대기열은 재시작 신호를 저장하기 위해 캐시를 사용하므로 이 기능을 사용하기 전에 캐시 드라이버를 구성해야 합니다. 🎜🎜🎜🎜
🎜🎜작업 만료 및 시간 초과🎜🎜작업 만료
🎜config/queue.php
구성 파일에서 각 대기열 연결은retry_after
를 정의합니다. 옵션. 이 옵션은 대기열 연결이 작업을 다시 시도하기 전에 대기해야 하는 시간을 지정합니다. 예를 들어,retry_after
값이90
으로 설정된 경우 작업은 삭제되지 않고 90초 실행 후 대기열에 다시 배치됩니다. 일반적으로 작업을 실행하는 데 가장 오랜 시간이 걸릴 것으로 생각되는 값으로retry_after
값을 설정해야 합니다. 🎜🎜{note}
retry_after
값은 Amazon SQS에만 존재하지 않습니다. SQS는 AWS 콘솔에 구성된 기본 표시 제한 시간 값을 기반으로 작업을 다시 시도합니다. 🎜🎜🎜🎜Processor Timeout
rrreeequeue:work
Artisan 명령에는--timeout
옵션이 포함되어 있습니다.--timeout
옵션은 작업을 실행하는 하위 프로세스를 중단하기 전에 Laravel의 큐 마스터가 기다리는 시간을 지정합니다. 때로는 외부 HTTP 요청에 응답하지 못하는 등 다양한 이유로 하위 프로세스가 "정지"될 수 있습니다.--timeout
옵션은 지정된 시간보다 오랫동안 정지된 프로세스를 제거합니다.queue:work
Artisan 命令包含一个--timeout
选项。--timeout
选项指定了 Laravel 的队列主进程在中止一个执行任务的子进程之前需要等到多久。有时一个子进程可能会因为各种原因「冻结」,比如一个外部的 HTTP 请求失去响应。--timeout
选项会移除那些超过指定时间被冻结的进程。retry_after
配置项和--timeout
命令行配置并不同,但将它们同时使用可以确保任务不会丢失并且任务只会成功执行一次。{note}
--timeout
的值应该比你在retry_after
中配置的值至少短几秒。这会确保处理器永远会在一个任务被重试之前中止。如果你的--timeout
值比retry_after
的值长的话,你的任务可能会被执行两次。队列进程睡眠时间
当任务在队列中可用时,处理器将会一直无间隔地处理任务。 然而,
rrreeesleep
选项定义了如果没有新任务的时候处理器将会「睡眠」多长时间。在处理器睡眠时,它不会处理任何新任务 —— 任务将会在队列处理器再次启动后执行。Supervisor 配置
安装 Supervisor
Supervisor 是 Linux 操作系统下中的一个进程监控器,它可以在
rrreeequeue:work
挂掉时自动重启之。在 Ubuntu 上安装 Supervisor,你可以使用如下命令:{小提醒} 如果觉得配置 Supervisor 难于登天,可以考虑使用 Laravel Forge,它将自动为你的 Laravel 项目安装和配置 Supervisor。
配置 Supervisor
Supervisor 的配置文件通常位于
rrreee/etc/supervisor/conf.d
目录下。在该目录中,你可以创建任意数量的配置文件,用来控制 supervisor 将如何监控你的进程。例如,创建一个laravel-worker.conf
文件使之启动和监控一个queue:work
进程:在这个例子中,
numprocs
指令将指定 Supervisor 运行 8 个queue:work
进程并对其进行监控,如果它们挂掉就自动重启它们。你应该更改command
选项中的queue:work sqs
rrreeeretry_after
구성 항목과--timeout
명령줄 구성은 다르지 않지만 함께 사용하면 작업이 손실되지 않고 작업이 한 번만 성공적으로 실행됩니다.{note}--timeout
값은retry_after
에서 구성한 값보다 최소한 몇 초 더 짧아야 합니다. 이렇게 하면 작업을 재시도하기 전에 프로세서가 항상 중단됩니다.--timeout
값이retry_after
값보다 길면 작업이 두 번 실행될 수 있습니다. 🎜🎜🎜큐 프로세스 휴면 시간🎜🎜큐에서 작업을 사용할 수 있으면 프로세서는 항상 간격 없이 작업을 처리합니다. 그러나sleep
옵션은 새로운 작업이 없을 경우 프로세서가 "잠자기"하는 시간을 정의합니다. 프로세서가 절전 모드인 동안에는 새로운 작업을 처리하지 않습니다. 대기열 프로세서가 다시 시작되면 작업이 실행됩니다. 🎜rrreee🎜🎜🎜감독자 구성
🎜🎜Install Supervisor🎜🎜Supervisor는 Linux 운영 체제의 프로세스 모니터로,queue:work
가 중단되면 자동으로 다시 시작할 수 있습니다. Ubuntu에 Supervisor를 설치하려면 다음 명령을 사용하면 됩니다. 🎜rrreee🎜{Tips} Supervisor 구성이 어렵다면 Laravel Forge는 Laravel 프로젝트에 대한 Supervisor를 자동으로 설치하고 구성합니다. 🎜
🎜🎜Supervisor 구성🎜🎜Supervisor의 구성 파일은 일반적으로/etc/supervisor/conf.d
디렉터리에 있습니다. . 이 디렉터리에서는 감독자가 프로세스를 모니터링하는 방법을 제어하기 위해 원하는 수의 구성 파일을 생성할 수 있습니다. 예를 들어queue:work
프로세스를 시작하고 모니터링하는laravel-worker.conf
파일을 생성합니다. 🎜rrreee🎜이 예에서는numprocs
지시어는 감독자가 8개의queue:work
프로세스를 실행하고 모니터링하며 중단되면 자동으로 다시 시작하도록 지정합니다. 원하는 대기열 연결을 나타내려면command
옵션의queue:work sqs
부분을 변경해야 합니다. 🎜🎜🎜Start Supervisor
구성 파일이 생성된 후 다음 명령을 사용하여 Supervisor 구성을 업데이트하고 프로세스를 시작할 수 있습니다.
rrreeeSupervisor에 대한 자세한 내용은 Supervisor 설명서를 확인하세요.
실패한 작업 처리
때때로 대기 중인 작업이 실행되지 않는 경우가 있습니다. 마음을 편하게 하세요. 좋은 일은 제때에만 옵니다. Laravel에는 작업을 시도해야 하는 최대 횟수를 지정하는 편리한 방법이 포함되어 있습니다. 작업이 최대 시도 횟수에 도달하면
rrreeefailed_jobs
데이터베이스 테이블에 삽입됩니다.failed_jobs
데이터베이스 마이그레이션 테이블을 생성하려면queue:failed-table
명령을 사용할 수 있습니다.failed_jobs
数据库表中。要创建failed_jobs
数据库迁移表,你可以使用queue:failed-table
命令:然后,当你运行 queue worker,你应该使用
rrreeequeue:work
命令中的--tries
开关指定应尝试运行任务的最大次数。 如果没有为--tries
选项指定值,则将死循环尝试运行任务:任务失败后清理
你可以直接在任务类中定义
rrreeefailed
方法,允许你在任务失败时执行针对于该任务的清理工作。 这是向用户发送警报或恢复任务执行的任何操作的绝佳位置。导致任务失败的Exception
将被传递给failed
方法:任务失败事件
如果你想在任务失败时注册一个可调用的事件,你可以使用
rrreeeQueue::failing
方法。该事件是通过 email 或 Slack 通知你团队的绝佳时机。例如,我们可以在 Laravel 中的AppServiceProvider
中附加一个回调事件:重试失败的任务
要想查看所有被放入
rrreeefailed_jobs
数据表中的任务,你可以使用 Artisan 命令queue:failed
:
rrreeequeue:failed
命令会列出任务 ID ,队列,以及失败的时间。任务 ID 可能会被用于重试失败的任务。例如,要重试一个任务 ID 为5
的任务,使用如下命令:要重试所有失败的任务,执行
rrreeequeue:retry
命令,将all
作为 ID 传入:如果你想删除一个失败的任务,使用
rrreeequeue:forget
命令:要清空所有失败的任务,使用
그런 다음 큐 작업자queue:flush
rrreee,
queue:work
명령에서--tries
스위치를 사용하여 작업을 시도해야 하는 최대 횟수를 지정해야 합니다 달리다.--tries
옵션에 값이 지정되지 않으면 무한 루프가 작업 실행을 시도합니다. rrreee작업 실패 후 정리
🎜작업 클래스에서 직접failed
메서드를 정의할 수 있습니다. 이 작업을 정리하기 위해 작업이 실패할 때 대상을 실행합니다. 이는 사용자에게 경고를 보내거나 작업에 의해 수행된 모든 작업을 재개하기에 좋은 장소입니다. 작업 실패를 유발하는예외
는failed
메서드로 전달됩니다: 🎜rrreee🎜🎜🎜🎜작업 실패 이벤트
🎜작업 실패 시 호출 가능한 이벤트를 등록하려면Queue::failing
방법. 이 이벤트는 이메일이나 Slack🎜을 통해 팀에 알릴 수 있는 좋은 기회입니다. 예를 들어, Laravel의AppServiceProvider
에 콜백 이벤트를 연결할 수 있습니다: 🎜rrreee🎜🎜🎜🎜실패한 작업 다시 시도
🎜failed_jobs
데이터 테이블에 있는 모든 작업을 보려면 Artisan 명령어queue:failed 를 사용할 수 있습니다. code>: 🎜rrreee🎜
ID로 전달: 🎜rrreee🎜 실패한 작업을 삭제하려면queue:failed
이 명령은 작업 ID, 대기열 및 실패 시간을 나열합니다. 작업 ID는 실패한 작업을 재시도하는 데 사용될 수 있습니다. 예를 들어 작업 ID가5
인 작업을 재시도하려면 다음 명령을 사용하세요. 🎜rrreee🎜실패한 모든 작업을 재시도하려면queue:retry
명령을 실행하고 < 코드를 바꾸세요. >allqueue:forget
명령을 사용하세요. 🎜rrreee🎜실패한 모든 작업을 지우려면를 사용하세요. 대기열:플러시
명령: 🎜rrreee🎜🎜🎜🎜🎜🎜누락된 모델 무시
Eloquent 모델을 작업에 주입하면 모델은 대기열에 넣기 전에 자동으로 직렬화되고 작업이 실행될 때 복원됩니다. 그러나 작업이 실행되기를 기다리는 동안 모델이 삭제되면 작업이 실패하고
ModelNotFoundException
이 발생할 수 있습니다.ModelNotFoundException
。为了方便,你可以选择设置任务的
rrreeedeleteWhenMissingModels
属性为true
来自动地删除缺失模型的任务。任务事件
通过在
rrreeeQueue
facade 中使用before
和after
方法,你可以指定一个队列任务被执行前后的回调。这些回调是添加额外的日志或增加统计的绝好时机。通常,你应该在 服务提供者中调用这些方法。例如,我们可以使用 Laravel 的AppServiceProvider
:在
편의를 위해 작업의Queue
facade 使用looping
deleteWhenMissingModels
속성을 true
로 설정하여 누락된 모델이 있는 작업을 자동으로 삭제할 수 있습니다.작업 이벤트
🎜큐
기준 Facade에서before
및after
메서드를 사용하면 대기열 작업이 실행되기 전후에 콜백을 지정할 수 있습니다. 이러한 콜백은 추가 로그를 추가하거나 통계를 늘릴 수 있는 좋은 기회입니다. 일반적으로 서비스 공급자에서 이러한 메서드를 호출해야 합니다. 예를 들어, Laravel의AppServiceProvider
를 사용할 수 있습니다: 🎜rrreee🎜프로세서가 콜백을 시도하기 전에 콜백을 실행하려면Queue
파사드의looping
메서드를 사용하세요. 임무를 얻습니다. 예를 들어 이전에 실패한 작업으로 인해 아직 닫히지 않은 트랜잭션을 롤백하기 위해 클로저를 사용할 수 있습니다. 🎜rrreee🎜이 기사는 🎜LearnKu.com🎜 웹사이트에 처음 게재되었습니다. 🎜🎜- Amazon SQS:
- Redis
- 사용자 지정 연결 및 대기열