Maison >développement back-end >Golang >Comment maximiser les requêtes HTTP simultanées dans Go ?

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

Linda Hamilton
Linda Hamiltonoriginal
2024-11-26 15:06:10692parcourir

How to Maximize Concurrent HTTP Requests in Go?

Comment maximiser efficacement les requêtes HTTP simultanées ?

Lorsque vous expérimentez les performances de Go, vous pouvez rencontrer des limitations lorsque vous tentez d'exécuter simultanément un volume élevé de requêtes HTTP. . Cet article explore les défis rencontrés et propose une solution pour atteindre une concurrence maximale.

Le problème

Votre approche initiale consiste à lancer un grand nombre de goroutines pour envoyer des requêtes HTTP en parallèle, en s'attendant à ce qu'elles utilisent tous les processeurs disponibles. Cependant, vous rencontrez des erreurs dues aux limites des descripteurs de fichiers.

La solution

Pour surmonter ces limitations, envisagez les approches suivantes :

  • Utilisez un canal sémaphore pour contrôler la concurrence : Implémentez un canal tamponné qui sert de sémaphore, limitant le nombre de requêtes simultanées. En ajustant la taille du tampon de canal et en ajustant GOMAXPROCS, vous pouvez optimiser la simultanéité de votre système.
  • Exploitez un pool de nœuds de calcul avec un répartiteur : Utilisez un modèle de pool de nœuds de calcul dans lequel les demandes sont mises en file d'attente dans un canal. . Un répartiteur remplit le canal, tandis qu'un groupe de travailleurs traite les demandes une par une. Cette approche garantit que le nombre maximum de requêtes simultanées est maintenu.
  • Utilisez une goroutine de consommateur dédiée pour traiter les réponses : Pour éviter de bloquer le traitement des demandes, employez une goroutine dédiée pour consommer les réponses du travailleur. piscine. Cela garantit une exécution continue des requêtes, permettant à votre système de gérer davantage de requêtes simultanées.

Code optimisé

Voici une version modifiée de votre code qui intègre ces optimisations :

package main

import (
    "fmt"
    "net/http"
    "runtime"
    "sync"
    "time"
)

var (
    reqs       int
    concurrent int
    work       chan *http.Request
    results    chan *http.Response
)

func init() {
    reqs = 1000000
    concurrent = 200
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    work = make(chan *http.Request, concurrent)
    results = make(chan *http.Response)
    start := time.Now()

    // Create a semaphore channel to limit concurrency
    sem := make(chan struct{}, concurrent)

    // Create a dispatcher to populate the work channel
    go func() {
        for i := 0; i < reqs; i++ {
            req, _ := http.NewRequest("GET", "http://localhost/", nil)
            work <- req
        }
        close(work) // Signal to workers that no more requests are incoming
    }()

    // Create a worker pool to process requests
    for i := 0; i < concurrent; i++ {
        go func() {
            for req := range work {
                resp, err := http.DefaultClient.Do(req)
                if err != nil {
                    fmt.Println(err)
                }
                results <- resp

                // Release semaphore token to allow another worker to proceed
                <-sem
            }
        }()
    }

    // Consume responses from worker pool
    var (
        conns int64
        totalSize int64
        wg     sync.WaitGroup
    )

    wg.Add(1)
    go func() {
        defer wg.Done()
        for {
            select {
            case resp, ok := <-results:
                if ok {
                    conns++
                    totalSize += resp.ContentLength
                    resp.Body.Close()
                } else {
                    return
                }
            }
        }
    }()

    // Block until all responses are processed
    wg.Wait()

    elapsed := time.Since(start)
    fmt.Printf("Connections:\t%d\nConcurrent:\t%d\nTotal size:\t%d bytes\nElapsed:\t%s\n", conns, concurrent, totalSize, elapsed)
}

En ajustant la variable concurrente et en observant les résultats, vous pouvez déterminer le niveau de concurrence optimal pour votre système, en « maximisant » sa capacité de HTTP simultané. demandes.

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!

Déclaration:
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