file d'attente
- Paramètres nécessaires pour le pilote
- Base de données
- Redis
- Autres Package d'extension de dépendance pilotée par file d'attente
- Créer des tâches
- Générer une classe de tâches
- Structure de classe de tâches
- Distribuer les tâches
- Chaîne de travail
- Connexion et file d'attente de la chaîne de travail
- Connexion et file d'attente personnalisées
- Distribuer les tâches à la file d'attente spécifiée
- Spécifier le nombre maximum de tentatives de tâche/la valeur du délai d'attente
- Timeout
- Fermeture de la file d'attente处 Exécutez le processeur de file d'attente
- exécutez la tâche unique
- pour gérer la tâche de toutes les files d'attente, puis quittez
- Précautions en matière de ressources
- Expiration de la tâche & Timeout
- Expiration des tâches
- Délai d'expiration du processeur
- Configurer le superviseur
- Démarrer le superviseur Gérer les tâches ayant échoué
- Événements de mission
File d'attente
- Introduction
- Créer une tâche
- Tâches de distribution
- Restrictions d'accès
- Gestion des erreurs Expiration et délai d'attente des tâches
- Configuration du superviseur Gérer les tâches ayant échoué Événements de tâches
- Introduction
- {tip} Laravel propose désormais Horizon, un magnifique tableau de bord et un système de configuration pour vos files d'attente Redis. Consultez la documentation complète d'Horizon pour plus d'informations.
- Laravel Queue fournit une API unifiée pour différents services de files d'attente backend, tels que Beanstalk, Amazon SQS, Redis et même d'autres files d'attente basées sur des bases de données relationnelles. Le but de la file d'attente est de retarder le traitement des tâches chronophages, telles que l'envoi d'e-mails, réduisant ainsi considérablement le temps de requêtes et de réponses Web. Le fichier de configuration de la file d'attente est stocké dans le fichier
config/queue.php
. La configuration de chaque pilote de file d'attente peut être trouvée dans ce fichier, y compris la base de données, Beanstalkd , Redis - et pilotes synchrones (utilisation locale). Il contient également un pilote de file d'attente
null
pour les tâches qui abandonnent la file d'attente. Connection Vs. Queue
Avant de commencer à utiliser la file d'attente Laravel, il est important de comprendre la différence entre « connexion » et « file d'attente ». Dans votre fichier de configuration
config/queue.php
, il y a une option de configurationconnections
. Cette option définit une connexion unique à un service backend tel qu'Amazon SQS, Beanstalk ou Redis. Quoi qu'il en soit, il peut y avoir plusieurs « files d'attente » pour une connexion donnée, et les « files d'attente » peuvent être considérées comme différentes piles ou un grand nombre de tâches en file d'attente.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 数据库轮询要更有效率的多。例如,你可以将这个值设置为
Il est à noter que l'exemple de configuration de chaque connexion dans le fichier de configuration5
queue
contient un attributqueue
. Il s'agit de la tâche de file d'attente par défaut qui sera distribuée à cette file d'attente lorsqu'elle sera envoyée à la connexion spécifiée. Autrement dit, si vous ne définissez pas explicitement de file d'attente lors de la distribution d'une tâche, elle sera placée dans la file d'attente définie par l'attributqueue
dans la configuration de la connexion :Certaines applications n'auront peut-être pas besoin de le faire. Les tâches sont envoyées vers différentes files d'attente, mais uniquement vers une simple file d'attente. Mais déplacer des tâches vers différentes files d'attente reste très utile, car le gestionnaire de file d'attente Laravel vous permet de définir la priorité de la file d'attente, vous pouvez donc attribuer différentes priorités à différentes files d'attente ou distinguer différentes méthodes de traitement pour différentes tâches. Par exemple, si vous transférez des tâches vers la file d'attente'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'retry_after' => 90, 'block_for' => 5, ],
haute
, vous pouvez laisser le processeur de file d'attente donner la priorité à ces tâches : 🎜php artisan make:job ProcessPodcast
🎜 🎜🎜🎜Paramètres nécessaires pour le pilote🎜 🎜Base de données
🎜Pour utiliser < code>base de données Pilote de file d'attente, vous avez besoin d'une table de données pour stocker les tâches. Exécutez la commandequeue:table
Artisan pour créer le fichier de migration pour cette table. Une fois le fichier de migration créé, vous pouvez utiliser la commandemigrate
pour migrer : 🎜<?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
🎜 Afin d'utiliser le pilote de file d'attenteredis
, vous devez configurer la connexion à la base de données Redis dans le fichier de configurationconfig/database.php
. 🎜🎜Redis Cluster🎜🎜Si votre pilote de file d'attente Redis utilise Redis Cluster, le nom de votre file d'attente doit contenir un balise de hachage de clé . Cela permet de garantir que toutes les clés Redis d'une file d'attente sont placées dans le même hachage. 🎜use App\Jobs\ProcessPodcast; $this->app->bindMethod(ProcessPodcast::class.'@handle', function ($job, $app) { return $job->handle($app->make(AudioProcessor::class)); });
🎜Blocage🎜🎜Lors de l'utilisation d'une file d'attente Redis, vous pouvez utiliser l'élément de configurationblock_for
pour spécifier que le pilote doit ressaisir la tâche dans la base de données Redis et interroger le processeur Depuis combien de temps a-t-il été bloqué auparavant. 🎜🎜Ajuster cette valeur en fonction de la charge de votre file d'attente est beaucoup plus efficace que de placer de nouvelles tâches dans la base de données Redis et de l'interroger. Par exemple, vous pouvez définir cette valeur sur5
pour indiquer que le pilote doit bloquer pendant 5 secondes en attendant que la tâche soit disponible. 🎜<?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); } }
🎜🎜Autres packages d'extension de dépendance de pilote de file d'attente
Avant d'utiliser le service de file d'attente dans la liste, vous devez installer les packages d'extension de dépendance suivants :
- Amazon SQS :
aws/aws-sdk-php ~3.0
- Beanstalkd:
pda/pheanstalk ~4.0
- Redis:
predis/predis ~1.0
aws/aws-sdk-php ~3.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) ->delay(now()->addMinutes(10)); } }
生成的类实现了
IlluminateContractsQueueShouldQueue
接口,这意味着这个任务将会被推送到队列中,而不是同步执行。任务类结构
任务类的结构很简单,一般来说只会包含一个让队列用来调用此任务的
handle
方法。我们来看一个示例的任务类。这个示例里,假设我们管理着一个播客发布服务,在发布之前需要处理上传播客文件:<?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); } }
注意,在这个例子中,我们在任务类的构造器中直接传递了一个 Eloquent 模型 。因为我们在任务类里引用了
SerializesModels
这个 trait,使得 Eloquent 模型在处理任务时可以被优雅地序列化和反序列化。如果你的队列任务类在构造器中接收了一个 Eloquent 模型,那么只有可识别出该模型的属性会被序列化到队列里。当任务被实际运行时,队列系统便会自动从数据库中重新取回完整的模型。这整个过程对你的应用程序来说是完全透明的,这样可以避免在序列化完整的 Eloquent 模式实例时所带来的一些问题。在队列处理任务时,会调用
handle
方法,而这里我们也可以通过handle
方法的参数类型提示,让 Laravel 的 服务容器 自动注入依赖对象。如果你想完全控制容器如何将依赖对象注入至
handle
方法,可以使用容器的bindMethod
方法。bindMethod
方法接受一个任务和容器的回调。虽然可以直接在回调中可以调用handle
方法,但建议应该从 service provider 调用为佳:ProcessPodcast::withChain([ new OptimizePodcast, new ReleasePodcast ])->dispatch();
{note} 像图片内容这种二进制数据,在放入队列任务之前必须使用
Redis :base64_encode
Beanstalkd :pda/pheanstalk ~4.0
predis/predis ~1.0
Créer des emplois
🎜 < div name="17bfa2" data-unique="17bfa2">🎜Générer des classes de tâches
🎜Dans votre application, les classes de tâches de la file d'attente sont placées dansapp/Jobs
répertoire. Si ce répertoire n'existe pas, il sera créé automatiquement lorsque vous exécuterez la commandemake:job
Artisan. Vous pouvez utiliser la commande Artisan suivante pour générer une nouvelle tâche de file d'attente : 🎜ProcessPodcast::withChain([ new OptimizePodcast, new ReleasePodcast ])->dispatch()->allOnConnection('redis')->allOnQueue('podcasts');
🎜La classe générée implémente l'interfaceIlluminateContractsQueueShouldQueue
, ce qui signifie que la tâche sera poussée vers la file d'attente plutôt que exécutée de manière synchrone. 🎜🎜🎜🎜🎜Structure de classe de tâches
🎜La structure de la classe de tâches est très simple, Dit généralement qu'il ne contiendra qu'une méthodehandle
que la file d'attente utilise pour appeler cette tâche. Regardons un exemple de classe de tâches. Dans cet exemple, supposons que nous gérons un service de publication de podcast et que nous devions traiter les fichiers podcast téléchargés avant de publier : 🎜<?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'); } }
🎜 Notez que dans cet exemple, nous passons un modèle Eloquent directement dans le constructeur de la classe de tâches. Étant donné que nous avons référencé le traitSerializesModels
dans la classe de tâches, le modèle Eloquent peut être sérialisé et désérialisé gracieusement lors du traitement des tâches. Si votre classe de tâches de file d'attente reçoit un modèle Eloquent dans le constructeur, seules les propriétés qui reconnaissent ce modèle seront sérialisées dans la file d'attente. Lorsque la tâche est effectivement exécutée, le système de file d'attente récupère automatiquement le modèle complet de la base de données. L'ensemble de ce processus est totalement transparent pour votre application, ce qui évite certains problèmes associés à la sérialisation d'instances de modèle Eloquent complètes. 🎜🎜Lorsque la file d'attente traite les tâches, la méthodehandle
sera appelée, et ici nous pouvons également utiliser l'indice de type de paramètre de la méthodehandle
pour laisser le conteneur de service de Laravel injecter automatiquement objets dépendants. 🎜🎜Si vous souhaitez avoir un contrôle total sur la façon dont le conteneur injecte les objets dépendants dans la méthodehandle
, vous pouvez utiliser la méthodebindMethod
du conteneur. La méthodebindMethod
accepte un rappel de tâche et de conteneur. Bien que la méthodehandle
puisse être appelée directement dans le rappel, il est recommandé de l'appeler depuis le fournisseur de services : 🎜<?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'); } }
🎜{note} Les données binaires telles que le contenu de l'image doivent être placées dans le tâche de file d'attente Vous devez utiliser la méthode
base64_encode
pour la convertir au préalable. Sinon, lorsque la tâche est placée dans la file d'attente, elle risque de ne pas être sérialisée correctement en JSON. 🎜🎜🎜🎜🎜🎜🎜🎜Distribuer les tâches
Une fois que vous avez fini d'écrire votre classe de tâches, vous pouvez utiliser sa propre méthode
dispatch
pour la distribuer. Les paramètres passés à la méthodedispatch
seront transmis au constructeur de la tâche :dispatch
方法分发它。传递给dispatch
方法的参数将会被传递给任务的构造函数:ProcessPodcast::dispatch($podcast) ->onConnection('sqs') ->onQueue('processing');
延迟分发
如果你想延迟你的队列任务的执行,你可以在分发任务的时候使用
delay
方法。例如,让我们详细说明一个十分钟之后才会执行的任务:php artisan queue:work --tries=3
{note} Amazon SQS 队列服务最大延迟 15 分钟的时间。
同步调度
如果您想立即(同步)执行队列任务,可以使用
dispatchNow
方法。 使用此方法时,队列任务将不会排队,并立即在当前进程中运行:<?phpnamespace App\Jobs;class ProcessPodcast implements ShouldQueue{ /** * 任务可以尝试的最大次数。 * * @var int */ public $tries = 5;}
工作链
工作链允许你具体定义一个按序列执行队列任务的列表。一旦序列中的任务失败了,剩余的工作将不会执行。要运行一个工作链,你可以对可分发的任务使用
withChain
方法:/** * 定义任务超时时间 * * @return \DateTime */ public function retryUntil(){ return now()->addSeconds(5); }
{note} 使用
$this->delete()
方法删除队列任务不会阻止工作链任务执行。只有当工作链中的任务执行失败时,工作链才会停止执行。工作链连接 & 队列
如果你想定义用于工作链的默认连接和队列,你可以使用
allOnConnection
和allOnQueue
方法。 这些方法指定了所需队列的连接和队列 —— 除非队列任务被明确指定给了不同的连接 / 队列:php artisan queue:work --timeout=30
自定义连接 & 队列
分发任务到指定队列
通过将任务分发到不同队列,你可以将你的队列任务「分类」,甚至指定给不同队列分配的任务数量。记住,这不是推送任务到你定义的队列配置文件的不同的连接里,而是一个单一的连接。要指定队列,在分发任务时使用
onQueue
方法:<?php namespace App\Jobs;class ProcessPodcast implements ShouldQueue{ /** * 任务可以执行的最大秒数 (超时时间)。 * * @var int */ public $timeout = 120;}
分发任务到指定连接
如果你在多队列连接中工作,你可以指定将任务分发到哪个连接。要指定连接,在分发任务时使用
onConnection
方法:Redis::throttle('key')->allow(10)->every(60)->then(function () { // 任务逻辑... }, function () { // 无法获得锁... return $this->release(10); });
当然,你可以链式调用
onConnection
和onQueue
Redis::funnel('key')->limit(1)->then(function () { // 任务逻辑...}, function () { // 无法获得锁... return $this->release(10); });
Distribution différée
Si vous souhaitez retarder l'exécution de votre tâche en file d'attente, vous pouvez utiliser la méthodedelay
lors de la distribution de la tâche. Par exemple, détaillons une tâche qui ne sera exécutée que dix minutes :{note} Le service de file d'attente Amazon SQS a une latence maximale de 15 minutes. 🎜🎜🎜🎜$podcast = App\Podcast::find(1); dispatch(function () use ($podcast) { $podcast->publish(); });
🎜envoi synchrone
🎜Si vous souhaitez immédiatement ( synchronous ) pour exécuter des tâches de file d'attente, vous pouvez utiliser la méthodedispatchNow
. Lors de l'utilisation de cette méthode, la tâche en file d'attente ne sera pas mise en file d'attente et exécutée immédiatement dans le processus en cours : 🎜php artisan queue:work
🎜🎜🎜🎜Chaîne de travail
🎜La chaîne de travail vous permet de définir spécifiquement une liste de tâches de file d'attente qui sont exécutées en séquence. Lorsqu'une tâche de la séquence échoue, le travail restant ne sera pas exécuté. Pour exécuter une chaîne de travail, vous pouvez utiliser la méthodewithChain
sur les tâches distribuables : 🎜php artisan queue:work redis
🎜{note} Utilisez la méthode
$this->delete()
La suppression d'une tâche de file d'attente n'empêche pas l'exécution de la tâche de chaîne de travail. La chaîne de travail cessera de s'exécuter uniquement lorsqu'une tâche de la chaîne de travail ne s'exécutera pas. 🎜🎜Connexions et files d'attente de la chaîne de travail
🎜Si vous souhaitez définir des connexions et des files d'attente par défaut pour les chaînes de travail, vous pouvez utiliser le < méthodes code>allOnConnection etallOnQueue
. Ces méthodes spécifient la connexion et la file d'attente de la file d'attente souhaitée - sauf si la tâche de file d'attente est explicitement affectée à une connexion/file d'attente différente : 🎜php artisan queue:work redis --queue=emails
🎜🎜🎜🎜Connexion et file d'attente personnalisées
🎜Distribuer les tâches dans la file d'attente spécifiée < /h4>🎜En répartissant les tâches dans différentes files d'attente, vous pouvez "catégoriser" vos tâches de file d'attente et même spécifier le nombre de tâches assignées aux différentes files d'attente. N'oubliez pas qu'il ne s'agit pas de transférer les tâches vers différentes connexions dans le fichier de configuration de file d'attente que vous définissez, mais vers une seule connexion. Pour spécifier une file d'attente, utilisez la méthode
onQueue
lors de la distribution des tâches : 🎜php artisan queue:work --once
🎜Distribuer les tâches à la connexion spécifiée
🎜 Si vous travaillez sur une connexion multi-files d'attente, vous pouvez spécifier sur quelle connexion distribuer la tâche. Pour spécifier une connexion, utilisez la méthodeonConnection
lors de la répartition des tâches : 🎜php artisan queue:work --stop-when-empty
🎜 Bien sûr, vous pouvez enchaîner les méthodesonConnection
etonQueue
pour spécifier la connexion et la file d'attente. 🎜dispatch((new Job)->onQueue('high'));
🎜🎜🎜🎜🎜🎜Spécifiez le nombre maximum de tentatives de tâche/la valeur du délai d'attente
Nombre maximum de tentatives
La spécification du nombre maximum de tentatives dans une tâche peut être spécifiée via l'option
--tries
de la commande Artisan :--tries
选项 指定:php artisan queue:work --queue=high,low
你可能想通过任务类自身对最大任务尝试次数进行一个更颗粒化的处理。如果最大尝试次数是在任务类中定义的,它将优先于命令行中的值提供:
php artisan queue:restart
基于时间的尝试
作为另外一个选择来定义任务在失败前会尝试多少次,你可以定义一个任务超时时间。这样的话,在给定的时间范围内,任务可以无限次尝试。要定义一个任务的超时时间,在你的任务类中新增一个
retryUntil
方法:php artisan queue:work --timeout=60
{tip} 你也可以在你的队列事件监听器中使用
retryUntil
方法。超时
{note}
timeout
特性对于 PHP 7.1+ 和pcntl
PHP 扩展进行了优化.同样的,任务执行最大秒数的数值可以通过 Artisan 命令行的
--timeout
php artisan queue:work --sleep=3
Vous souhaiterez peut-être Un traitement plus granulaire du nombre maximum de tentatives de tâches est effectué via la classe de tâches elle-même. Si le nombre maximum de tentatives est défini dans la classe de tâche, il sera fourni de préférence à la valeur sur la ligne de commande :sudo apt-get install supervisor
Tentatives basées sur le tempsAu lieu de définir le nombre de tentatives d'une tâche avant d'échouer, vous pouvez définir un délai d'expiration de la tâche. De cette façon, la tâche peut être tentée un nombre illimité de fois dans un laps de temps donné. Pour définir le délai d'expiration d'une tâche, ajoutez une méthoderetryUntil
à votre classe de tâches : 🎜[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
🎜{tip} Vous pouvez également utiliser la méthode
retryUntil
de votre file d'attente. 🎜🎜🎜Timeout🎜🎜{note} Fonctionnalité
🎜De même, la valeur du nombre maximum de secondes pour l'exécution de la tâche peut être spécifiée via l'optiontimeout
pour PHP 7.1+ etpcntl< /code> L'extension PHP a été optimisée. 🎜
--timeout
sur la ligne de commande Artisan. 🎜sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:*
🎜Cependant, vous souhaiterez peut-être également définir un délai d'attente dans la classe de tâches elle-même. Si spécifiée dans la classe de tâche, la priorité sera supérieure à la ligne de commande : 🎜php artisan queue:failed-table php artisan migrate
🎜🎜🎜🎜🎜🎜Limitation de fréquence
{note} Cette fonctionnalité nécessite que votre application puisse utiliser un serveur Redis
Si votre application utilise Redis, vous pouvez limiter vos tâches de file d'attente par temps ou par simultanéité. Cette fonctionnalité est utile lorsque vos tâches de file d'attente sont consommées via une API dont le débit est également limité.
Par exemple, en utilisant la méthode
throttle
, vous pouvez limiter une tâche d'un type donné à seulement 10 fois toutes les 60 secondes. Si le verrou n'est pas acquis, vous devez généralement remettre la tâche dans la file d'attente afin qu'elle puisse être réessayée ultérieurement.throttle
方法,你可以限制一个给定类型的任务每 60 秒只执行 10 次。如果没有获得锁,一般情况下你应该将任务放回队列以使其可以被稍后重试。php artisan queue:work redis --tries=3
{tip} 在上述的例子里,
key
可以是任何你想要限制频率的任务类型的唯一识别字符串。例如,使用构件基于任务类名的 key,或它操作的 Eloquent 模型的 ID。{note} 将受限制的作业释放回队列,仍然会增加工作的总数
attempts
。或者,你可以指定一个任务可以同时执行的最大数量。在如下情况时这会很有用处:当一个队列中的任务正在修改资源时,一次只能被一个任务修改。例如,使用
funnel
方法,你可以限制一个给定类型的任务一次只能执行一个处理器:<?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} 当使用频率限制时,任务执行成功的尝试的次数可能会难以确定。所以,将频率限制与 时间限制 组合是很有作用的。
错误处理
如果在任务执行的时候出现异常,任务会被自动释放到队列中以再次尝试。任务将会一直被释放直到达到应用允许的最大重试次数。最大重试的数值由
queue:work
Artisan 命令的--tries
<?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} Dans l'exemple ci-dessus, lakey
peut être n'importe quelle chaîne d'identification unique pour le type de tâche dont vous souhaitez limiter la fréquence. Par exemple, utilisez la clé d'un widget en fonction du nom de la classe de tâches ou de l'ID du modèle Eloquent sur lequel il fonctionne.{note} Le fait de remettre des tâches restreintes dans la file d'attente augmente toujours le nombre total de tâches
Vous pouvez également spécifier le nombre maximum de tâches pouvant être exécutées simultanément. Cela peut être utile lorsqu'une tâche dans une file d'attente modifie une ressource qui ne peut être modifiée que par une tâche à la fois. Par exemple, en utilisant la méthodetentatives
.funnel
, vous pouvez limiter une tâche d'un type donné à un seul processeur à la fois :php artisan queue:failed
{tip} Lors de l'utilisation de la limitation de fréquence, le nombre de tentatives réussies exécution des tâches Cela peut être difficile à déterminer. Il est donc utile de combiner les limites de fréquence avec les limites de temps
.Gestion des erreursSi une exception se produit lors de l'exécution de la tâche, la tâche sera automatiquement libérée Faites la queue pour réessayer. La tâche sera libérée jusqu'à ce que le nombre maximum de tentatives autorisées par l'application soit atteint. La valeur maximale de nouvelle tentative est définie par l'optionci-dessous 🎜 . 🎜🎜🎜🎜🎜🎜🎜🎜Fermeture de la file d'attente🎜🎜Vous pouvez également appeler la fermeture directement au lieu de planifier la classe de tâches dans la file d'attente. Ceci est utile pour les tâches simples et rapides qui doivent être effectuées : 🎜--tries
de la commandequeue:work
Artisan, ou dans la classe de tâches. Plus d'informations sur les gestionnaires de files d'attente d'exécution peuvent être trouvéesphp artisan queue:retry 5
🎜 Lorsqu'une fermeture est envoyée à une file d'attente, le contenu du code de la fermeture est signé cryptographiquement afin qu'il ne puisse pas être modifié en cours de transport. 🎜🎜🎜🎜🎜🎜🎜Run Queue Handler
Laravel comprend un gestionnaire de file d'attente pour exécuter les tâches placées dans la file d'attente. Vous pouvez utiliser la commande
queue:work
Artisan pour exécuter le processeur. Notez qu'une fois que la commandequeue:work
démarre son exécution, elle continuera à s'exécuter jusqu'à ce qu'elle soit arrêtée manuellement ou que le terminal soit fermé.queue:work
Artisan 命令运行处理器。 注意一旦queue:work
命令开始执行,它会一直运行直到它被手动停止或终端被关闭。php artisan queue:retry all
{tip} 要使
queue:work
进程一直在后台运行,你应该使用进程管理器比如 Supervisor 来确保队列处理器不会停止运行记住,队列处理器是一个常驻的进程并且在内存中保存着已经启动的应用状态。因此,它们并不会在启动后注意到你代码的更改。所以,在你的重新部署过程中,请记得 重启你的队列处理器.
指定连接 & 队列
你也可以具体说明队列处理器应该使用哪个队列连接。 传递给
work
的连接名应该与你的config/queue.php
配置文件中定义的连接之一相符。php artisan queue:forget 5
你甚至可以自定义你的队列处理器使其只执行连接中指定的队列。例如,如果你的所有邮件都由
redis
连接的emails
队列处理,你可以使用如下的命令启动一个仅执行此队列的处理器:php artisan queue:flush
执行单一任务
--once
选项用于使队列处理器只处理队列中的单一任务。/** * 如果模型缺失即删除任务。 * * @var bool */ public $deleteWhenMissingModels = true;
处理所有队列的任务然后退出
--stop-when-empty
选项可用于处理队列处理器处理所有作业然后优雅地退出。如果您希望在队列为空后关闭容器,则在 Docker 容器中运行 Laravel 队列时,此选项很有用:<?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() { // } }
资源注意事项
后台驻留的队列处理器不会在执行完每个任务后「重启」框架。因此,你应该在每个任务完成后释放任何占用过大的资源。例如,如果你正在用 GD 库执行图像处理,你应该在完成后使用
imagedestroy
Queue::looping(function () { while (DB::transactionLevel() > 0) { DB::rollBack(); } });
{tip} Pour que le processus
N'oubliez pas que le processeur de file d'attente est un processus résident et conserve l'état de l'application démarrée en mémoire. Par conséquent, ils ne remarqueront pas les modifications apportées à votre code après le démarrage. Ainsi, pendant votre processus de redéploiement, n'oubliez pas de redémarrez vos processeurs de file d'attente .queue:work
s'exécute en arrière-plan, vous devez utiliser un gestionnaire de processus tel que Supervisorpour assurez-vous que la file d'attente Le processeur ne s'arrête pas de fonctionner
Spécifier la connexion et la file d'attente
🎜Vous pouvez également spécifier quelle connexion de file d'attente le gestionnaire de file d'attente doit utiliser. Le nom de connexion transmis àwork
doit correspondre à l'une des connexions définies dans votre fichier de configurationconfig/queue.php
. 🎜rrreee🎜Vous pouvez même personnaliser votre gestionnaire de file d'attente pour exécuter uniquement la file d'attente spécifiée dans la connexion. Par exemple, si tous vos emails sont traités par la file d'attenteemails
connectée àredis
, vous pouvez démarrer un processeur qui n'exécute que cette file d'attente à l'aide de la commande suivante : 🎜rrreee🎜Exécuter une seule tâche
🎜L'option--once
est utilisée pour que le processeur de file d'attente ne traite qu'une seule tâche dans la file d'attente. 🎜rrreee🎜Traitez toutes les tâches en file d'attente, puis quittez
🎜--l'option stop-when-empty
peut être used Le gestionnaire de file d'attente de traitement traite toutes les tâches, puis se termine correctement. Cette option est utile lors de l'exécution d'une file d'attente Laravel dans un conteneur Docker si vous souhaitez arrêter le conteneur une fois la file d'attente vide : 🎜rrreee🎜Resource Notes
🎜Le processeur de file d'attente résident en arrière-plan ne "redémarrera" pas le framework après l'exécution de chaque tâche. Par conséquent, vous devez libérer toutes les ressources excessives une fois chaque tâche terminée. Par exemple, si vous effectuez un traitement d'image avec la bibliothèque GD, vous devez utiliserimagedestroy
pour libérer la mémoire lorsque vous avez terminé. 🎜🎜🎜🎜🎜🎜🎜Priorité de la file d'attente
Parfois, vous souhaiterez peut-être donner la priorité à l'exécution de la file d'attente. Par exemple, dans
rrreeeconfig/queue.php
vous pouvez définir la priorité de la file d'attentequeue
connectée parredis
à partir dedefault
estfaible
. Cependant, vous souhaiterez peut-être parfois placer une tâche dans la file d'attentehaute
comme suit :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 中不存在
Pour exécuter un processeur afin de confirmer que la tâche dans la file d'attenteretry_after
rrreeebasse
est dans toutes Les tâches de file d'attente>high
ne seront exécutées qu'une fois terminées. Vous pouvez transmettre une liste de noms de file d'attente séparés par des virgules comme arguments à la commandework
.🎜🎜Processeur de file d'attente et déploiement🎜🎜Parce que les processeurs de file d'attente sont résidents processus, ils n’appliqueront pas les modifications à votre code jusqu’à ce qu’ils soient redémarrés. Par conséquent, le moyen le plus simple de déployer une application utilisant un processeur de file d'attente consiste à redémarrer le processeur de file d'attente pendant le processus de déploiement. Vous pouvez redémarrer gracieusement tous les processeurs de file d'attente en utilisant la méthodequeue:restart
: 🎜rrreee🎜Cette commande demandera à tous les processeurs de file d'attente d'"abandonner" gracieusement après avoir terminé la tâche en cours, il n'y aura donc pas de mission perdue. . Étant donné que le gestionnaire de file d'attente se terminera après l'exécution dequeue:restart
, vous devez exécuter un gestionnaire de processus tel que Supervisor pour redémarrer automatiquement le processeur de file d'attente. 🎜🎜{tip} Les files d'attente utilisent le cache pour stocker les signaux de redémarrage, vous devez donc vous assurer de configurer le pilote de cache avant d'utiliser cette fonctionnalité. 🎜🎜🎜🎜
🎜🎜Expiration et délais d'attente des tâches🎜🎜Expiration des tâches
🎜Dans votre fichier de configurationconfig/queue.php
, chaque connexion à la file d'attente définit unretry_after
option. Cette option spécifie combien de temps la connexion à la file d'attente doit attendre une tâche avant de la réessayer. Par exemple, si la valeur deretry_after
est définie sur90
, alors la tâche sera remise dans la file d'attente après 90 secondes d'exécution plutôt que d'être supprimée. En général, vous devez définir la valeur deretry_after
sur la valeur dont vous pensez que l'exécution de votre tâche est susceptible de prendre le plus de temps. 🎜🎜{note} La valeur
retry_after
n'existe pas uniquement dans Amazon SQS. SQS réessayera la tâche en fonction de la valeur de délai d'expiration visible par défaut configurée dans la console AWS. 🎜🎜🎜🎜Processor Timeout
rrreeequeue:work
La commande Artisan contient une option--timeout
. L'option--timeout
spécifie combien de temps le processus maître de file d'attente de Laravel attend avant d'abandonner un processus enfant exécutant une tâche. Parfois, un processus enfant peut « se bloquer » pour diverses raisons, telles que l'incapacité de répondre à une requête HTTP externe. L'option--timeout
supprimera les processus qui ont été gelés pendant plus longtemps que la durée spécifiée.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
进程:在这个例子中,
L'élément de configurationnumprocs
指令将指定 Supervisor 运行 8 个queue:work
进程并对其进行监控,如果它们挂掉就自动重启它们。你应该更改command
选项中的queue:work sqs
rrreeeretry_after
et la configuration de la ligne de commande--timeout
ne sont pas différents, mais les utiliser ensemble peut garantir que la tâche ne sera pas perdue et que la tâche sera ne sera exécuté avec succès qu'une seule fois.{note} La valeur de--timeout
doit être au moins quelques secondes plus courte que la valeur que vous configurez dansretry_after
. Cela garantit que le processeur abandonnera toujours avant qu'une tâche puisse être réessayée. Si votre valeur--timeout
est plus longue que la valeurretry_after
, votre tâche peut être exécutée deux fois. 🎜🎜🎜Temps de veille du processus de file d'attente🎜🎜Lorsque la tâche est disponible dans la file d'attente, le processeur traitera toujours la tâche sans aucun intervalle. Cependant, l'optionsleep
définit la durée pendant laquelle le processeur « dormira » s'il n'y a pas de nouvelles tâches. Pendant que le processeur est en veille, il ne traitera aucune nouvelle tâche - les tâches seront exécutées au redémarrage du processeur de file d'attente. 🎜rrreee🎜🎜🎜Configuration du superviseur
🎜🎜Install Supervisor🎜🎜Supervisor est un moniteur de processus sous le système d'exploitation Linux. Il peut redémarrer automatiquement lorsquequeue:work
se bloque. Pour installer Supervisor sur Ubuntu, vous pouvez utiliser la commande suivante : 🎜rrreee🎜{Tips} Si vous avez des difficultés à configurer Supervisor, vous pouvez envisager d'utiliser Laravel Forge, qui installera et configurera automatiquement Supervisor pour votre projet Laravel. 🎜
🎜🎜Configuration du superviseur🎜🎜Le fichier de configuration du superviseur se trouve généralement dans le répertoire/etc/supervisor/conf.d
. Dans ce répertoire, vous pouvez créer n'importe quel nombre de fichiers de configuration pour contrôler la manière dont le superviseur surveillera votre processus. Par exemple, créez un fichierlaravel-worker.conf
qui démarre et surveille un processusqueue:work
: 🎜rrreee🎜Dans cet exemple,numprocs
La directive spécifiera au superviseur d'exécuter 8 processusqueue:work
et de les surveiller, et de les redémarrer automatiquement s'ils se bloquent. Vous devez modifier la partiequeue:work sqs
de l'optioncommand
pour représenter la connexion à la file d'attente souhaitée. 🎜🎜🎜Démarrer le Superviseur
Une fois le fichier de configuration créé, vous pouvez utiliser la commande suivante pour mettre à jour la configuration du Superviseur et démarrer le processus :
rrreeePour plus d'informations sur le Superviseur, vous pouvez consulter la Documentation du Superviseur.
Gestion des tâches ayant échoué
Parfois, vos tâches en file d'attente ne s'exécuteront pas. Détendez-vous, les bonnes choses n’arrivent qu’avec le temps. Laravel inclut une méthode pratique pour spécifier le nombre maximum de fois qu'une tâche doit être tentée. Si un travail a atteint le nombre maximum de tentatives, il est inséré dans la table de la base de données
rrreeefailed_jobs
. Pour créer la table de migration de la base de donnéesfailed_jobs
, vous pouvez utiliser la commandequeue: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
命令:要清空所有失败的任务,使用
Ensuite, lorsque vous exécutez queue workerqueue:flush
rrreee, vous devez utiliser le commutateur
--tries
dans la commandequeue:work
pour spécifier le nombre maximum de fois où la tâche doit être tentée courir. Si aucune valeur n'est spécifiée pour l'option--tries
, une boucle infinie tentera d'exécuter la tâche : rrreeeNettoyer après échec d'une tâche
🎜Vous pouvez définir la méthodefailed
directement dans la classe de tâche, vous permettant pour exécuter la cible lorsque la tâche échoue pour le nettoyage de cette tâche. C'est un excellent endroit pour envoyer des alertes à l'utilisateur ou reprendre toute action effectuée par la tâche. L'Exception
qui provoque l'échec de la tâche sera transmise à la méthodefailed
: 🎜rrreee🎜🎜🎜🎜Événement d'échec de tâche
🎜Si vous souhaitez enregistrer un événement appelable lorsqu'une tâche échoue, vous pouvez utiliser laQueue::failing
méthode. Cet événement est le moment idéal pour informer votre équipe par e-mail ou Slack🎜. Par exemple, nous pouvons attacher un événement de rappel àAppServiceProvider
dans Laravel : 🎜rrreee🎜🎜🎜🎜Réessayer les tâches ayant échoué
🎜Pour afficher toutes les tâches qui ont été placées dans la table de donnéesfailed_jobs
, vous pouvez utiliser la commande Artisanqueue:failed code> : 🎜rrreee🎜
Transmettez-le comme ID : 🎜rrreee🎜 Si vous souhaitez supprimer une tâche ayant échoué, utilisez la commandequeue:failed
La commande répertoriera l'ID de la tâche, la file d'attente et l'heure d'échec. L'ID de tâche peut être utilisé pour réessayer les tâches ayant échoué. Par exemple, pour réessayer une tâche avec l'ID de tâche5
, utilisez la commande suivante : 🎜rrreee🎜Pour réessayer toutes les tâches ayant échoué, exécutez la commandequeue:retry
et remplacez < code >allqueue:forget
: 🎜rrreee🎜Pour effacer toutes les tâches ayant échoué, utilisezqueue:flush
Commande : 🎜rrreee🎜🎜🎜🎜🎜🎜Ignorer les modèles manquants
Lors de l'injection d'un modèle Eloquent dans une tâche, le modèle sera automatiquement sérialisé avant d'être mis en file d'attente et restauré lors de l'exécution de la tâche. Cependant, si le modèle est supprimé alors que la tâche est en attente d'exécution, la tâche peut échouer et lancer
ModelNotFoundException
.ModelNotFoundException
。为了方便,你可以选择设置任务的
rrreeedeleteWhenMissingModels
属性为true
来自动地删除缺失模型的任务。任务事件
通过在
rrreeeQueue
facade 中使用before
和after
方法,你可以指定一个队列任务被执行前后的回调。这些回调是添加额外的日志或增加统计的绝好时机。通常,你应该在 服务提供者中调用这些方法。例如,我们可以使用 Laravel 的AppServiceProvider
:在
Pour plus de commodité, vous pouvez choisir de définir l'attributQueue
facade 使用looping
deleteWhenMissingModels
de la tâche surtrue
pour supprimer automatiquement les tâches avec des modèles manquants.Événements de tâches
🎜ParFile d'attente
En utilisant les méthodesbefore
etafter
dans la façade, vous pouvez spécifier un rappel avant et après l'exécution d'une tâche de file d'attente. Ces rappels constituent une excellente opportunité d’ajouter des journaux supplémentaires ou d’augmenter les statistiques. Normalement, vous devez appeler ces méthodes auprès du fournisseur de services. Par exemple, nous pouvons utiliser leAppServiceProvider
de Laravel : 🎜rrreee🎜Utilisez la méthodelooping
dans la façadeQueue
pour exécuter un rappel avant que le processeur ne tente de obtenir la tâche. Par exemple, vous souhaiterez peut-être utiliser une fermeture pour annuler des transactions qui n'ont pas encore été fermées par une tâche ayant échoué précédemment : 🎜rrreee🎜Cet article est apparu pour la première fois sur le site Web 🎜LearnKu.com🎜. 🎜🎜- Amazon SQS :
- Spécifiez la connexion et la file d'attente