Développement Laravel5 min de lecture

Moderniser avec Laravel : files d’attente, idempotence et migration sans risque

Modernisez progressivement une application PHP existante grâce à des écritures transactionnelles, des jobs rejouables sans danger et un plan de retour arrière répété.

Une transaction applicative qui alimente une file d'attente et des workers indépendants

La réponse courte

Migrez une fonctionnalité métier à la fois. Protégez les invariants de la base de données avec des transactions et des contraintes, rendez les jobs en file d'attente rejouables sans danger, et vérifiez la livraison et le retour arrière avant de déplacer la route suivante.

Choisissez un périmètre assez petit pour être vérifié

Une migration progressive peut réduire la portée de chaque mise en production, mais elle n’est pas sans risque. Commencez par un flux délimité dont les entrées, les sorties et les responsables sont bien compris. Cartographiez le modèle de données existant, les effets externes et les dépendances de reporting avant de basculer du trafic.

Relevez comme référence le taux d’erreurs, la latence des réponses, l’âge de la file d’attente et les résultats métier, comme les commandes finalisées. Dirigez un ensemble contrôlé de requêtes vers la nouvelle implémentation et conservez un chemin de retour clair. Évitez de migrer en même temps le stockage, le framework, les paiements et l’interface, sauf si les dépendances l’imposent.

Gardez l’écriture critique transactionnelle

Validez les permissions et les données saisies, puis enregistrez la transition d’état minimale valide dans une transaction de base de données. Utilisez des contraintes d’unicité pour les invariants, par exemple une seule référence externe par commande. Les verrous de ligne ou les mises à jour conditionnelles peuvent protéger les transitions concurrentes lorsqu’ils sont bien utilisés.

Un verrou Redis peut coordonner le travail, mais un bail expiré, un plantage ou une clé mal délimitée peuvent laisser des exécutions se chevaucher. Il ne remplace pas les contraintes de la base de données. Documentez quel système est responsable de chaque invariant et testez-le avec des requêtes simultanées.

Ne déclenchez un job qu’une fois les données validées

Un worker peut s’exécuter avant que la transaction qui l’a créé ne soit validée. Laravel permet de déclencher un job après la validation, pour qu’il ne lise pas des enregistrements non validés ou annulés. Dans une application Laravel 12, un schéma de base ressemble à ceci :

DB::transaction(function () use ($validated) {
    $order = Order::create($validated);
    ProcessOrder::dispatch($order->id)->afterCommit();
});

Cet exemple est volontairement incomplet : l’autorisation, la gestion des requêtes en double et la validation métier viennent s’y ajouter. Le déclenchement après validation n’élimine pas non plus la fenêtre de panne entre la validation en base et la remise à une file d’attente externe. Pour les flux qui exigent une livraison durable, envisagez un outbox transactionnel et un publieur qui réessaie.

Concevez les jobs pour une exécution « au moins une fois »

Partez du principe qu’un job peut s’exécuter plusieurs fois. Enregistrez une clé d’idempotence, suivez les opérations terminées et utilisez le mécanisme d’idempotence du fournisseur externe lorsqu’il existe. Ne marquez pas un job comme terminé avant que l’effet externe n’ait réussi. Rapprochez les résultats incertains au lieu de répéter aveuglément un débit ou une expédition.

  • Définissez les délais d’expiration, les limites de tentatives et les temporisations selon l’opération.
  • Gardez le délai d’expiration du worker inférieur à l’intervalle de nouvelle tentative de la file, avec une marge pour l’arrêt, afin de limiter les tentatives qui se chevauchent.
  • Surveillez les jobs en échec et l’âge de la file ; une réponse HTTP 202 signifie « accepté », pas « terminé ».
  • Redémarrez les workers de longue durée lors des mises en production pour qu’ils chargent le bon code.

Répétez les pannes et le retour arrière

Testez un webhook en double, le plantage d’un worker après un appel externe, un interblocage en base de données, une panne de la file d’attente et un déploiement raté. Vérifiez les enregistrements et les effets obtenus, pas seulement la réponse HTTP. Ajoutez un rapprochement pour le travail accepté mais jamais terminé.

Utilisez des changements de schéma rétrocompatibles tant que les deux applications sont actives. Définissez les conditions de retour arrière avant la mise en production et vérifiez que l’ancienne application sait lire les données écrites par la nouvelle. Gardez une source de vérité unique pour chaque enregistrement tant que la synchronisation n’est pas conçue explicitement.

Questions fréquentes

Quand un traitement doit-il rester synchrone ?

Lorsque l’appelant a besoin d’un résultat immédiat et définitif, et que le traitement est assez court pour respecter le temps de réponse prévu. Les files d’attente sont utiles pour le travail différable, mais elles apportent leurs propres responsabilités de livraison, de visibilité et de reprise.

Le déclenchement après validation garantit-il que le job arrive dans la file ?

Non. Il empêche de déclencher un job avant la validation de sa transaction, mais une panne peut encore survenir entre la validation et la remise à une file externe. Si vous avez besoin d’une livraison durable, évaluez un outbox transactionnel avec un publieur qui réessaie et un rapprochement.

Comment éviter que les nouvelles tentatives créent des paiements ou des commandes en double ?

Utilisez des clés d’idempotence persistantes, des contraintes en base de données et le mécanisme d’idempotence du fournisseur externe lorsqu’il existe. Suivez les résultats et rapprochez les réponses incertaines. Un verrou de courte durée ne couvre pas à lui seul tous les plantages ni toutes les fenêtres de nouvelle tentative.

Qu’est-ce qui facilite le retour arrière d’une migration progressive ?

Déplacer un flux délimité, conserver un chemin clair vers l’implémentation précédente et utiliser des changements de schéma rétrocompatibles. Vérifiez que l’ancienne application sait lire les enregistrements créés par la nouvelle. Définissez avant la mise en production les déclencheurs de retour arrière, fondés sur les erreurs et les résultats métier.

Sources et lectures complémentaires

Pour aller plus loin

Comparez les stratégies de rendu ou parlons d’une migration vers Laravel.

Paul Edward

Écrit par Paul Edward

Développeur web full-stack senior spécialisé en PHP, Laravel, WordPress et systèmes web assistés par l’IA.

En savoir plus sur Paul

Leave a Reply

Your email address will not be published. Required fields are marked *

Chargement d’une vérification rapide… (JavaScript requis)

Brief du projet Étape 1 sur 2 · Le travail

Que voulez-vous faire construire ?

Un paragraphe suffit pour commencer. Si ce n’est pas un travail pour moi, je vous le dirai et je vous orienterai vers quelqu’un de mieux placé.

Le travail

Cochez tout ce qui s’applique.

Plateforme

« Je ne sais pas » est une réponse tout à fait valable.

Que cherchez-vous à construire, et que doit-il faire pour les personnes qui l’utilisent ? Écrivez-le comme vous le diriez à voix haute.

0 / 1200

Deux étapes. Moins d’une minute.