Maison > développement back-end > Golang > Comment maximiser les requêtes HTTP simultanées dans Go à l'aide de Goroutines et de pools de travailleurs ?

Comment maximiser les requêtes HTTP simultanées dans Go à l'aide de Goroutines et de pools de travailleurs ?

Patricia Arquette
Libérer: 2024-12-02 01:40:10
original
945 Les gens l'ont consulté

How to Maximize Concurrent HTTP Requests in Go Using Goroutines and Worker Pools?

Comment maximiser les requêtes HTTP simultanées dans Go

De nombreux langages et frameworks de programmation fournissent des outils pour effectuer des requêtes HTTP, mais si vous devez envoyer un grand nombre de requêtes simultanément, il est essentiel de comprendre comment maximiser la simultanéité pour optimiser les performances. Cet article approfondira les subtilités de la « maximisation » des requêtes HTTP simultanées dans Go, en utilisant des goroutines pour libérer tout le potentiel des capacités de traitement de votre système.

Le problème :

Considérons un scénario dans lequel nous souhaitons générer un million de requêtes HTTP vers une URL spécifique le plus rapidement possible, en utilisant plusieurs goroutines. Cependant, le code fourni dans le message initial a entraîné des erreurs dues au dépassement des limites des descripteurs de fichiers. Il s'agit d'un problème courant lorsque l'on tente de gérer un grand nombre de requêtes simultanées.

La solution :

Pour maximiser efficacement la simultanéité, nous pouvons résoudre la limitation du descripteur de fichier en en utilisant un canal tamponné comme mécanisme de sémaphore dans un modèle de pool de travailleurs. Voici un aperçu de la solution :

  • Groupe de travailleurs :

    • Créez un pool de travailleurs qui gère le nombre de goroutines traitant les requêtes HTTP .
    • Chaque routine de travail traite une demande à la fois et signale quand elle est prête. un autre.
  • Canal Sémaphore :

    • Utilisez un canal tamponné avec une capacité limitée pour contrôler le nombre de HTTP simultanés requêtes.
    • Lorsqu'une routine de travail termine une requête, elle signale le canal sémaphore, permettant à une autre requête d'être traité.
  • Répartiteur :

    • Le répartiteur génère en continu des requêtes HTTP et les envoie au pool de travailleurs via une requête canal.
    • Au fur et à mesure que les travailleurs deviennent disponibles, le répartiteur extrait les demandes du canal et les affecte à travailleurs.
  • Consommateur :

    • Une goroutine distincte surveille le canal de réponse et incrémente le nombre de connexions pour chaque réponse valide . Il calcule également le temps de réponse moyen.

Code optimisé :

package main

import (
    "flag"
    "fmt"
    "log"
    "net/http"
    "runtime"
    "time"
)

var (
    reqs int
    max  int
)

func init() {
    flag.IntVar(&reqs, "reqs", 1000000, "Total requests")
    flag.IntVar(&max, "concurrent", 200, "Maximum concurrent requests")
}

type Response struct {
    *http.Response
    err error
}

// Dispatcher
func dispatcher(reqChan chan *http.Request) {
    defer close(reqChan)
    for i := 0; i < reqs; i++ {
        req, err := http.NewRequest("GET", "http://localhost/", nil)
        if err != nil {
            log.Println(err)
        }
        reqChan <- req
    }
}

// Worker Pool
func workerPool(reqChan chan *http.Request, respChan chan Response) {
    t := &amp;http.Transport{}
    for i := 0; i < max; i++ {
        go worker(t, reqChan, respChan)
    }
}

// Worker
func worker(t *http.Transport, reqChan chan *http.Request, respChan chan Response) {
    for req := range reqChan {
        resp, err := t.RoundTrip(req)
        r := Response{resp, err}
        respChan <- r
    }
}

// Consumer
func consumer(respChan chan Response) (int64, int64) {
    var (
        conns int64
        size  int64
    )
    for conns < int64(reqs) {
        select {
        case r, ok := <-respChan:
            if ok {
                if r.err != nil {
                    log.Println(r.err)
                } else {
                    size += r.ContentLength
                    if err := r.Body.Close(); err != nil {
                        log.Println(r.err)
                    }
                }
                conns++
            }
        }
    }
    return conns, size
}

func main() {
    flag.Parse()
    runtime.GOMAXPROCS(runtime.NumCPU())
    reqChan := make(chan *http.Request)
    respChan := make(chan Response)
    start := time.Now()
    go dispatcher(reqChan)
    go workerPool(reqChan, respChan)
    conns, size := consumer(respChan)
    took := time.Since(start)
    ns := took.Nanoseconds()
    av := ns / conns
    average, err := time.ParseDuration(fmt.Sprintf("%d", av) + "ns")
    if err != nil {
        log.Println(err)
    }
    fmt.Printf("Connections:\t%d\nConcurrent:\t%d\nTotal size:\t%d bytes\nTotal time:\t%s\nAverage time:\t%s\n", conns, max, size, took, average)
}
Copier après la connexion

Ce code amélioré combine les éléments évoqués précédemment pour créer un système basé sur un pool de travailleurs très efficace pour envoyer simultanément un grand volume de requêtes HTTP. En contrôlant soigneusement le nombre de requêtes simultanées via le canal sémaphore, nous pouvons éviter tout problème lié aux limites des descripteurs de fichiers et maximiser l'utilisation des ressources de notre système.

En résumé, en utilisant des goroutines, un canal sémaphore, un pool de travailleurs et un consommateur dédié pour gérer les réponses, nous pouvons efficacement « maximiser » les requêtes HTTP simultanées dans Go. Cette approche nous permet d'effectuer des tests de performance et des tests de résistance de manière efficace, en repoussant nos systèmes jusqu'aux limites et en obtenant des informations précieuses sur leurs capacités.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal