Découvrez comment utiliser Symfony Messenger pour gérer les tâches asynchrones et améliorer les performances de votre application PHP. Guide pratique avec des exemples concrets pour passer du synchrone à l'asynchrone sans prise de tête.
Salut ! 👋 Si vous en avez marre des temps de chargement qui s'éternisent ou des processus qui bloquent votre application, vous êtes au bon endroit. Aujourd'hui, on va parler d'un composant super puissant de Symfony : Messenger. Et promis, pas besoin d'être un expert pour suivre !
Pourquoi l'asynchrone va changer votre vie de dev ?
Imaginez que vous commandez un café. En mode synchrone, vous restez planté devant le barista jusqu'à ce que votre café soit prêt. En asynchrone ? Vous commandez, on vous donne un bip, et vous pouvez aller faire autre chose en attendant. Cool, non ?
Dans une app web, c'est pareil. L'asynchrone permet à votre application de :
- Répondre instantanément à vos utilisateurs 🏃♂️
- Gérer plus de requêtes simultanées 💪
- Éviter les timeouts sur les processus longs ⏱️
- Isoler les tâches pour une meilleure fiabilité 🛡️
De la théorie à la pratique
Exemple classique : l'envoi d'email
Avant (mode synchrone) 😴 :
public function register(User $user)
{
$this->userRepository->save($user);
$this->mailer->send($welcomeEmail); // L'utilisateur attend... attend... attend...
return $this->json(['status' => 'success']);
}
Après (mode asynchrone) 🚀 :
public function register(User $user)
{
$this->userRepository->save($user);
$this->messageBus->dispatch(new SendWelcomeEmail($user->getId())); // Hop, en file d'attente !
return $this->json(['status' => 'success']); // Réponse immédiate
}
Le tutoriel pas à pas 👣
On va installer et configurer Messenger ensemble. Je vous explique chaque étape !
1. Préparation du projet
D'abord, assurez-vous d'avoir un projet Symfony fonctionnel. Si ce n'est pas le cas :
symfony new my-messenger-project --webapp
cd my-messenger-project
2. Installation de Messenger
Installez le composant avec Composer :
composer require symfony/messenger
Cette commande va :
- Installer le package symfony/messenger
- Créer le fichier de configuration
config/packages/messenger.yaml
- Ajouter les variables d'environnement nécessaires dans
.env
- Créer une migration pour la table de messages si Doctrine est installé
3. Configuration du transport
3.1 Configuration de l'environnement
Dans votre .env
, vous trouverez une nouvelle ligne. Modifiez-la :
# .env
###> symfony/messenger ###
MESSENGER_TRANSPORT_DSN=doctrine://default
###< symfony/messenger ###
💡 Pro tip : En développement, vous pouvez aussi utiliser in-memory://default
pour des tests rapides.
3.2 Configuration de Messenger
Créez ou modifiez config/packages/messenger.yaml
:
framework:
messenger:
# Configuration par défaut
default_bus: messenger.bus.default
# Définition des transports
transports:
async_email:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
queue_name: async_email
# Retry strategy
retry_strategy:
max_retries: 3
delay: 1000
multiplier: 2
# Configuration du routing
routing:
'App\Message\SendEmailMessage': async_email
# Configuration des bus
buses:
messenger.bus.default:
middleware:
- doctrine_transaction
Expliquons chaque partie :
-
default_bus
: Définit le bus par défaut pour l'envoi des messages -
transports
: Configure comment les messages sont stockés et transportés -
routing
: Associe les messages à leurs transports -
buses
: Configure les middleware pour le traitement des messages
4. Préparation de la base de données
Si vous utilisez Doctrine, créez la migration :
php bin/console doctrine:migrations:diff
Appliquez la migration :
php bin/console doctrine:migrations:migrate
Cette migration va créer la table messenger_messages
qui stockera vos messages asynchrones.
5. Test de l'installation
Vérifions que tout fonctionne :
# Liste les commandes disponibles pour Messenger
php bin/console messenger:
# Démarre un worker pour traiter les messages
php bin/console messenger:consume async_email
Si tout est vert, félicitations ! 🎉 Messenger est correctement installé et configuré.
3. Créez votre premier message
namespace App\Message;
class SendEmailMessage
{
private string $to;
private string $subject;
private string $content;
public function __construct(string $to, string $subject, string $content)
{
$this->to = $to;
$this->subject = $subject;
$this->content = $content;
}
// N'oubliez pas les getters !
}
💡 Pro tip : Gardez vos messages simples ! Stockez des IDs plutôt que des objets entiers.
4. Créez votre handler
namespace App\MessageHandler;
use App\Message\SendEmailMessage;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class SendEmailMessageHandler implements MessageHandlerInterface
{
public function __invoke(SendEmailMessage $message)
{
// Votre logique d'envoi d'email ici
}
}
Les bonnes pratiques à connaître
Ce qu'il faut faire ✅
- Utilisez des IDs dans vos messages
- Loggez les erreurs
- Pensez à la validation des données
- Prévoyez la gestion des échecs
Ce qu'il faut éviter ❌
- Stocker des objets complexes dans les messages
- Oublier de gérer les erreurs
- Créer des dépendances circulaires
FAQ
Q: Combien de workers dois-je lancer ?
R: Commencez avec 1
worker par type de message. Ajustez selon vos besoins.
Q: Comment débugger les messages ?
R: Utilisez la commande php bin/console messenger:failed-messages
pour voir les messages en erreur.
Q: Que faire si un message échoue ?
R: Messenger réessaie automatiquement. Configurez le nombre de tentatives dans votre config.
Pour aller plus loin 🎯
En conclusion
L'asynchrone avec Symfony Messenger, c'est comme avoir un assistant personnel qui gère les tâches longues pendant que vous vous concentrez sur l'essentiel. Plus besoin de faire attendre vos utilisateurs, plus de timeouts intempestifs, juste une application qui répond au doigt et à l'œil ! 🎯
N'hésitez pas à nous contacter si vous souhaitez un accompagnement dans la mise en place de vos process asynchrone !