Dans un monde où les pannes de services cloud comme Redis ou SQS peuvent transformer une application robuste en chaos silencieux, Laravel 12.34 introduit le Failover Queue Driver. Cette fonctionnalité, imaginée et implémentée par Taylor Otwell lui-même, permet à vos jobs de queue de rebondir automatiquement vers un driver de backup si le principal flanche. Plus de jobs perdus, plus d'alertes paniquées à 3h du matin : Laravel gère le failover en toute transparence.
Annoncée le 14 octobre 2025 via un tweet viral de Taylor – "Today's Laravel release introduced a new 'failover' queue driver. It's now super easy to failover to executing jobs synchronously if your primary queue driver is down" – cette feature a déjà conquis la communauté avec plus de 450 likes et 60 reposts. Inspiré par des idées anciennes (comme ce ticket GitHub de 2016), c'est le remède ultime contre les interruptions. Plongeons dans les détails techniques, avec un exemple complet et une explication pas à pas.
Qu’est-ce que le Failover Queue Driver ?
Le Failover Queue Driver est un wrapper intelligent autour de plusieurs connexions de queue. Il :
- Tente d'abord le driver principal (ex. : Redis pour la vitesse),
- Si ça échoue (timeout, panne, surcharge), bascule automatiquement vers le suivant (ex. : base de données, ou même
syncpour une exécution immédiate), - Continue jusqu'à succès ou épuisement de la liste,
- Déclenche un événement
QueueFailedOverpour logger ou alerter sur le basculement.
Avant : Une panne Redis = jobs bloqués ou perdus, workers en panique.
Maintenant :QUEUE_CONNECTION=failover= résilience intégrée, zéro intervention manuelle.
C'est particulièrement puissant en production : imaginez un pic de trafic Black Friday où Redis surchauffe – vos emails transactionnels ou traitements batchs continuent via la DB sans que l'utilisateur ne s'en rende compte.
1. Configuration : Simple comme Bonjour
Dans config/queue.php
Ajoutez une connexion failover qui liste vos drivers en ordre de priorité :
1'connections' => [2 // Vos drivers existants3 'redis' => [4 'driver' => 'redis',5 'connection' => 'default',6 'queue' => env('REDIS_QUEUE', 'default'),7 'retry_after' => 90,8 'block_for' => null,9 ],1011 'database' => [12 'driver' => 'database',13 'table' => 'jobs',14 'queue' => 'default',15 'retry_after' => 90,16 'after_commit' => false,17 ],1819 'sync' => [20 'driver' => 'sync',21 ],2223 // La magie : le failover24 'failover' => [25 'driver' => 'failover',26 'connections' => [27 'redis', // Premier choix : rapide et scalable28 'database', // Backup : persistant et fiable29 'sync', // Dernier recours : synchrone, sans worker30 ],31 ],32],1'connections' => [2 // Vos drivers existants3 'redis' => [4 'driver' => 'redis',5 'connection' => 'default',6 'queue' => env('REDIS_QUEUE', 'default'),7 'retry_after' => 90,8 'block_for' => null,9 ],1011 'database' => [12 'driver' => 'database',13 'table' => 'jobs',14 'queue' => 'default',15 'retry_after' => 90,16 'after_commit' => false,17 ],1819 'sync' => [20 'driver' => 'sync',21 ],2223 // La magie : le failover24 'failover' => [25 'driver' => 'failover',26 'connections' => [27 'redis', // Premier choix : rapide et scalable28 'database', // Backup : persistant et fiable29 'sync', // Dernier recours : synchrone, sans worker30 ],31 ],32],
Dans .env
Définissez-le comme default :
1QUEUE_CONNECTION=failover1QUEUE_CONNECTION=failover
Workers : Un par Connexion
Lancez des workers pour chaque driver (sauf sync, qui n'en a pas besoin) :
1php artisan queue:work redis --queue=default2php artisan queue:work database --queue=default1php artisan queue:work redis --queue=default2php artisan queue:work database --queue=default
Astuce : Avec Laravel Horizon, monitorez tout en un dashboard unifié. Les workers non-Redis (comme
database) nécessitent des processus séparés.
2. Comment Ça Marche ? Le Mécanisme Étape par Étape
- Dispatch d'un Job : Vous appelez
dispatch(MyJob::class). - Tentative Primaire : Laravel push le job vers
redis. - Détection d'Échec : Si Redis renvoie une exception (ex. :
Connection refused), pas de panique. - Basculement Automatique : Essai sur
database. Succès ? Job sauvé ! - Événement Trigger :
QueueFailedOverest émis avec détails (connexion échouée, job concerné). - Fallback Ultime : Si tout rate,
syncexécute le job immédiatement dans le processus courant (mais attention : ça peut ralentir la réponse HTTP).
Exemple Complet : Gérer une Panne Redis
Imaginons un job SendWelcomeEmail qui envoie un email de bienvenue.
1// app/Jobs/SendWelcomeEmail.php2namespace App\Jobs;34use Illuminate\Bus\Queueable;5use Illuminate\Contracts\Queue\ShouldQueue;6use Illuminate\Foundation\Bus\Dispatchable;7use Illuminate\Queue\InteractsWithQueue;8use Illuminate\Queue\SerializesModels;9use Illuminate\Support\Facades\Mail;1011class SendWelcomeEmail implements ShouldQueue12{13 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;1415 public function __construct(public $user) {}1617 public function handle(): void18 {19 Mail::to($this->user->email)->send(new \App\Mail\WelcomeMail($this->user));20 }21}1// app/Jobs/SendWelcomeEmail.php2namespace App\Jobs;34use Illuminate\Bus\Queueable;5use Illuminate\Contracts\Queue\ShouldQueue;6use Illuminate\Foundation\Bus\Dispatchable;7use Illuminate\Queue\InteractsWithQueue;8use Illuminate\Queue\SerializesModels;9use Illuminate\Support\Facades\Mail;1011class SendWelcomeEmail implements ShouldQueue12{13 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;1415 public function __construct(public $user) {}1617 public function handle(): void18 {19 Mail::to($this->user->email)->send(new \App\Mail\WelcomeMail($this->user));20 }21}
Dispatch dans un Contrôleur
1// app/Http/Controllers/AuthController.php2use App\Jobs\SendWelcomeEmail;34public function register(Request $request)5{6 // ... création user ...78 // Dispatch avec failover automatique9 SendWelcomeEmail::dispatch($user);1011 return response()->json(['message' => 'Inscription réussie ! Email en cours...']);12}1// app/Http/Controllers/AuthController.php2use App\Jobs\SendWelcomeEmail;34public function register(Request $request)5{6 // ... création user ...78 // Dispatch avec failover automatique9 SendWelcomeEmail::dispatch($user);1011 return response()->json(['message' => 'Inscription réussie ! Email en cours...']);12}
Si Redis est down :
- Le job atterrit en DB → traité par le worker
database. - L'utilisateur voit une réponse instantanée, sans timeout.
Écouter l'Événement pour Alerter
1// app/Providers/EventServiceProvider.php2use Illuminate\Queue\Events\QueueFailedOver;3use Illuminate\Support\Facades\Event;45Event::listen(QueueFailedOver::class, function (QueueFailedOver $event) {6 \Log::warning('Failover activé !', [7 'from_connection' => $event->fromConnection,8 'job' => $event->job->resolveName(),9 ]);1011 // Optionnel : Slack ou email admin12 // \Illuminate\Support\Facades\Notification::route('slack', 'channel')->notify(new QueueFailoverAlert($event));13});1// app/Providers/EventServiceProvider.php2use Illuminate\Queue\Events\QueueFailedOver;3use Illuminate\Support\Facades\Event;45Event::listen(QueueFailedOver::class, function (QueueFailedOver $event) {6 \Log::warning('Failover activé !', [7 'from_connection' => $event->fromConnection,8 'job' => $event->job->resolveName(),9 ]);1011 // Optionnel : Slack ou email admin12 // \Illuminate\Support\Facades\Notification::route('slack', 'channel')->notify(new QueueFailoverAlert($event));13});
Fonctionnalités Clés du Failover Queue Driver
| Fonctionnalité | Description |
|---|---|
connections array |
Liste prioritaire des drivers à tester (Redis → DB → Sync). |
QueueFailedOver event |
Hook pour logging/alertes sur basculement. |
| Support multi-drivers | Redis, SQS, Database, Beanstalkd, etc. |
| Pas de retry automatique | Basculement immédiat ; si tous échouent, exception levée. |
| Compatible Horizon | Monitoring unifié, mais workers séparés. |
deferred comme fallback |
Nouveau en 12.35 : exécution post-réponse HTTP sans bloquer. |
Intégration avec Laravel Horizon (Dashboard)
Installez Horizon pour visualiser les failovers :
1composer require laravel/horizon2php artisan horizon:install3php artisan horizon1composer require laravel/horizon2php artisan horizon:install3php artisan horizon
Dans l'interface :
- Metrics : Taux de failovers par connexion.
- Failed Jobs : Jobs impactés, avec raison (ex. : "Redis down").
- Tags : Marquez les jobs pour tracer les basculements.
Pourquoi c’est une Révolution pour la Résilience ?
| Avant (Laravel 11) | Après (Laravel 12.34) |
|---|---|
| Panne Redis = jobs perdus ou manuels | Auto-failover vers DB/sync en <1s |
| Config manuelle pour backups | Un array connections suffit |
| Pas d'événement natif | QueueFailedOver pour monitoring pro |
| Workers bloqués sur une connexion | Workers indépendants, jobs redirigés |
| Risque de downtime total | Uptime 99.99% sans effort |
Taylor l'a prototypé en une matinée le 10 octobre, suite à des idées communautaires datant de 2016. Résultat : un système "set it and forget it" qui sauve des millions de jobs par jour en prod.
Mise à Jour & Compatibilité
1composer require laravel/framework:^12.342php artisan queue:table # Si DB pas encore configurée3php artisan migrate1composer require laravel/framework:^12.342php artisan queue:table # Si DB pas encore configurée3php artisan migrate
Aucun breaking change. Fonctionne avec tous les drivers officiels. Testez en staging : simulez une panne Redis avec
docker stop redis.
Limitations :
- Failover au push seulement (pas au drain des workers).
- Si tous les drivers échouent, le job lève une exception.
pushRaw()ne trigger pas l'événement (seulementpush()etlater()).
Use Cases Réels
- E-commerce : Panne SQS → fallback DB pour commander processing (millions d'€ en jeu).
- SaaS : Redis down → sync pour notifications critiques, DB pour batchs.
- Fintech : Multi-régions : Redis EU → DB US en cas de outage géo.
- API Heavy : 10k jobs/heure → failover transparent, zéro perte.
Conclusion
Le Failover Queue Driver transforme Laravel en une forteresse imprenable contre les pannes de queue. Comme le dit Taylor : "super easy to failover" – et c'est vrai. Plus de sueurs froides quand Redis tousse : vos jobs continuent, votre app respire.
Taylor Otwell sur X :
"If your main queue connection is down you can failover to a backup connection, even 'sync'. Thoughts? 🫶"
→ 226 likes, buzz immédiat.
À vous de jouer : Ajoutez 'failover' à votre config/queue.php et dormez tranquille. La résilience n'a jamais été aussi simple.
Liens utiles :