Cet article vous apporte une introduction à l'utilisation des files d'attente dans le framework laravel (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Dans le développement de projets réels, nous rencontrons souvent des situations qui nécessitent des files d'attente légères, comme l'envoi de messages texte, l'envoi d'e-mails, etc. Ces tâches ne suffisent pas pour utiliser des files d'attente de messages lourdes telles que kafka et RabbitMQ, mais Et ça nécessite des fonctions telles que le contrôle asynchrone, de nouvelle tentative et de concurrence. De manière générale, nous utilisons souvent Redis, Beanstalk et Amazon SQS pour implémenter les fonctions associées. Laravel fournit une API unifiée pour différents services de file d'attente en arrière-plan. Cet article présentera la file d'attente Redis la plus largement utilisée.
Avant d'expliquer le service de file d'attente de Laravel, nous devons d'abord parler du service de file d'attente basé sur Redis. Tout d'abord, Redis est conçu pour la mise en cache, mais en raison de certaines de ses propres caractéristiques, il peut être utilisé pour les files d'attente de messages
Les fonctionnalités de file d'attente de messages de Redis telles que FIFO (premier entré, premier sorti) sont faciles à implémenter. Vous n'avez besoin que d'un objet de liste pour récupérer les données du début et remplir les données de la fin.
Commandes associées : (1) Entrée gauche et sortie droite : lpush/rpop ; (2) Entrée droite et sortie gauche : rpush/lpop.
Cette file d'attente de messages simple est facile à mettre en œuvre.
Certains scénarios de tâches ne nécessitent pas que la tâche soit exécutée immédiatement, mais doivent être retardées. Certaines tâches sont très importantes et doivent être réessayées lorsque la tâche échoue. Ces fonctions ne peuvent pas être accomplies uniquement en s'appuyant sur des listes. À l’heure actuelle, une collection ordonnée de Redis est nécessaire.
L'ensemble ordonné Redis est similaire à l'ensemble Redis, c'est une collection qui ne contient pas la même chaîne. La différence entre eux est que chaque membre de l’ensemble ordonné est associé à un score, qui est utilisé pour classer les membres de l’ensemble ordonné du score le plus bas au score le plus élevé.
En regardant uniquement l'ensemble ordonné et les tâches retardées, il n'y a pas de relation, mais vous pouvez définir le score de l'ensemble ordonné sur l'heure à laquelle la tâche retardée est démarrée, puis interroger l'ensemble ordonné pour récupérer le tâches expirées. Sortez pour le traitement, réalisant ainsi la fonction de retarder les tâches.
Pour les tâches importantes qui doivent être réessayées, avant que la tâche ne soit exécutée, la tâche sera placée dans une collection ordonnée et le temps d'exécution le plus long de la tâche sera défini. Si la tâche est exécutée avec succès, la tâche sera supprimée de la collection commandée. Si la tâche n'est pas terminée dans le délai imparti, les tâches de l'ensemble ordonné seront remises dans la file d'attente.
Commandes associées :
(1) ZADD Ajoute un ou plusieurs membres à un ensemble ordonné, ou met à jour son score s'il existe déjà.
(2) ZRANGEBYSCORE Renvoie un ensemble ordonné de plages de membres par score.
(3) ZREMRANGEBYRANK Supprime tous les membres d'un ensemble ordonné dans l'index donné.
Le processus de planification des tâches du service de file d'attente est le suivant :
Le service de file d'attente de Laravel se compose de deux Il existe deux contrôles de processus, l'un est le producteur et l'autre est le consommateur. Ces deux processus manipulent trois files d'attente Redis, dont l'une est List, responsable des tâches immédiates, et deux Zsets, responsables des tâches retardées et des tâches en attente.
Le producteur est responsable de pousser les tâches vers redis. S'il s'agit d'une tâche immédiate, elle sera poussée vers queue:default par défaut ; retardé.
Le consommateur interroge deux files d'attente, retire continuellement des tâches de la file d'attente, place d'abord les tâches dans queue:default:reserved, puis exécute les tâches associées. Si la tâche est exécutée avec succès, la tâche dans queue:default:reserved sera supprimée, sinon elle sera remise dans la file d'attente queue:default:delayed.
Processus de distribution des tâches :
Fonctionnement du processeur de tâches :
'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'retry_after' => 90, ],
Configurer dans config/queue.php
De manière générale, la configuration par défaut de Redis est comme ci-dessus. connection est le nom de connexion de redis dans la base de données ; queue est le nom de la file d'attente dans redis. Il convient de noter que si vous utilisez un cluster redis, vous devez utiliser la balise de hachage de clé, qui est {default}. ; lorsque la tâche est en cours d'exécution. Une fois le délai retry_after dépassé, la tâche sera remise dans la file d'attente.
La structure de la classe de tâches est très simple. De manière générale, elle ne contient qu'une méthode handle que la file d'attente utilise pour appeler cette tâche.
Si vous souhaitez que les tâches soient placées dans la file d'attente plutôt que exécutées de manière synchrone, vous devez implémenter l'interface IlluminateContractsQueueShouldQueue.
Si vous souhaitez envoyer des tâches vers une connexion spécifique, telle que redis ou sqs, vous devez définir la variable de connexion.
Si vous souhaitez pousser la tâche vers une file d'attente spécifique, vous pouvez définir la variable de file d'attente.
如果想要让任务延迟推送,那么需要设置 delay 变量。
如果想要设置任务至多重试的次数,可以使用 tries 变量;
如果想要设置任务可以运行的最大秒数,那么可以使用 timeout 参数。
如果想要手动访问队列,可以使用 trait : IlluminateQueueInteractsWithQueue。
任务的分发
分发服务
写好任务类后,就能通过 dispatch 辅助函数来分发它了。唯一需要传递给 dispatch 的参数是这个任务类的实例:
class PodcastController extends Controller { public function store(Request $request) { // 创建播客... ProcessPodcast::dispatch($podcast); } }
如果想延迟执行一个队列中的任务,可以用任务实例的 delay 方法。
ProcessPodcast::dispatch($podcast) ->delay(Carbon::now()->addMinutes(10));
通过推送任务到不同的队列,可以给队列任务分类,甚至可以控制给不同的队列分配多少任务。要指定队列的话,就调用任务实例的 onQueue 方法:
ProcessPodcast::dispatch($podcast)->onQueue('processing');
如果使用了多个队列连接,可以将任务推到指定连接。要指定连接的话,可以在分发任务的时候使用 onConnection 方法:
ProcessPodcast::dispatch($podcast)->onConnection('redis ');
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!