Files d'attente et tâches d'arrière-plan en Go : goroutines, canaux et motifs avancés

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi Go est-il le langage idéal pour les files d'attente et les tâches d'arrière-plan ?

\n\n

Si vous avez déjà écrit un backend en Python ou Node.js, vous avez sûrement rencontré ce problème : l'application traite une requête, mais en même temps, elle doit envoyer un email, générer un rapport ou traiter un fichier téléchargé. Si vous le faites de manière synchrone, l'utilisateur attend. Si vous le faites dans un thread séparé, vous commencez à danser avec les verrous et les conditions de concurrence.

\n\n

Go résout ce problème de manière élégante et native. Les goroutines et les canaux (channels) sont des mécanismes de concurrence intégrés qui rendent le développement de files d'attente et de tâches d'arrière-plan en Go simple et sûr. Dans cet article, nous verrons comment organiser le traitement d'arrière-plan en utilisant à la fois la bibliothèque standard et des outils populaires comme RabbitMQ. Vous verrez des exemples de code concrets que vous pouvez appliquer immédiatement dans votre projet.

\n\n

Les bases : goroutines et canaux

\n\n

Avant de plonger dans les files d'attente, rappelons les bases. Une goroutine est un fil d'exécution léger qui est lancé avec le mot-clé go. Un canal est un « pipeline » typé à travers lequel les goroutines communiquent entre elles.

\n\n

Exemple simple : envoi d'email asynchrone

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc sendEmail(email string) {\n    time.Sleep(2 * time.Second) // simulation d'une opération longue\n    fmt.Println("Email sent to", email)\n}\n\nfunc main() {\n    fmt.Println("Start")\n    go sendEmail("user@example.com") // lancement en arrière-plan\n    fmt.Println("Continue processing...")\n    time.Sleep(3 * time.Second) // attend la fin de la goroutine\n}
\n\n

Ici, sendEmail s'exécute en arrière-plan, tandis que le flux principal n'est pas bloqué. Mais que faire si vous devez traiter 1000 emails ? Lancer 1000 goroutines n'est pas une bonne idée : elles commenceront à se faire concurrence pour les ressources. C'est là que les canaux et le motif Worker Pool viennent à la rescousse.

\n\n

Le motif Worker Pool en Go

\n\n

Le Worker Pool est une approche classique pour organiser les files d'attente et les tâches d'arrière-plan en Go. Vous avez un nombre fixe de workers (goroutines) qui écoutent un seul canal de tâches. Les tâches arrivent du flux principal ou d'un gestionnaire HTTP.

\n\n

Implémentation du Worker Pool

\n\n
package main\n\nimport (\n    "fmt"\n    "sync"\n    "time"\n)\n\ntype Task struct {\n    ID   int\n    Data string\n}\n\nfunc worker(id int, tasks <-chan Task, wg *sync.WaitGroup) {\n    defer wg.Done()\n    for task := range tasks {\n        fmt.Printf("Worker %d processing task %d: %s\\n", id, task.ID, task.Data)\n        time.Sleep(1 * time.Second) // simulation de travail\n    }\n}\n\nfunc main() {\n    const numWorkers = 3\n    tasks := make(chan Task, 10) // canal tamponné\n\n    var wg sync.WaitGroup\n\n    // Lancement des workers\n    for i := 1; i <= numWorkers; i++ {\n        wg.Add(1)\n        go worker(i, tasks, &wg)\n    }\n\n    // Envoi des tâches\n    for i := 1; i <= 10; i++ {\n        tasks <- Task{ID: i, Data: fmt.Sprintf("Task %d", i)}\n    }\n    close(tasks) // fermeture du canal pour que les workers se terminent\n\n    wg.Wait()\n    fmt.Println("All tasks completed")\n}
\n\n

Ce code crée 3 workers qui traitent 10 tâches. Le canal tamponné permet d'envoyer des tâches sans blocage, tant que le tampon n'est pas plein. Ce motif est parfait pour les tâches d'arrière-plan en Golang dans les applications web : vous recevez une requête, placez la tâche dans le canal et répondez immédiatement à l'utilisateur.

\n\n

Files d'attente en Go avec RabbitMQ

\n\n

Pour les systèmes distribués, les canaux en mémoire ne suffisent pas : vous avez besoin d'un stockage externe de files d'attente. RabbitMQ est l'un des courtiers de messages les plus populaires. Voyons comment le connecter à une application Go.

\n\n

Installation et connexion

\n\n

Commencez par installer la bibliothèque amqp :

\n\n
go get github.com/rabbitmq/amqp091-go
\n\n

Producteur (envoi de tâches)

\

Blogs

Book Recommendations