Maison  >  Article  >  développement back-end  >  Comment puis-je maximiser efficacement les requêtes HTTP simultanées en Go tout en évitant l'épuisement des ressources système ?

Comment puis-je maximiser efficacement les requêtes HTTP simultanées en Go tout en évitant l'épuisement des ressources système ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-26 01:39:09819parcourir

How Can I Efficiently Maximize Concurrent HTTP Requests in Go While Avoiding System Resource Exhaustion?

Maximisation efficace des requêtes HTTP simultanées dans Go

Dans votre code, vous avez tenté d'envoyer simultanément 1 million de requêtes HTTP, mais vous avez rencontré des erreurs dues aux limitations du descripteur de fichier. Voici comment « inonder » efficacement votre ordinateur portable de requêtes dans les limites des contraintes du système :

Code modifié à l'aide de la concurrence basée sur les canaux :

<br>package main </p>
<p>importer (</p>
<pre class="brush:php;toolbar:false">"flag"
"fmt"
"log"
"net/http"
"runtime"
"sync"
"time"

)

var (

reqs int
max  int

)

func init() {

flag.IntVar(&amp;reqs, "reqs", 1000000, "Total requests")
flag.IntVar(&amp;max, "concurrent", 200, "Maximum concurrent requests")

}

type Structure de réponse {

*http.Response
err error

}

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
}

}

func workerPool(reqChan chan http.Request, respChan chan Response, wg sync.WaitGroup) {

t := &amp;http.Transport{}
for i := 0; i < max; i++ {
    go worker(t, reqChan, respChan, wg)
}

}

func worker(t http.Transport, reqChan chan http.Request, respChan chan Response, wg *sync.WaitGroup) {

for req := range reqChan {
    resp, err := t.RoundTrip(req)
    r := Response{resp, err}
    respChan <- r
}
wg.Done()

}

consommateur func (réponse respChan chan) (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, max)
respChan := make(chan Response)
wg := sync.WaitGroup{}
wg.Add(max)

start := time.Now()
go dispatcher(reqChan)
go workerPool(reqChan, respChan, &amp;wg)
conns, size := consumer(respChan)
wg.Wait()
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)

}

Explication :

  • Répartiteur : Crée un canal de requête et envoie des requêtes HTTP à it.
  • Worker Pool : Crée un pool de goroutines qui consomment simultanément les requêtes du canal de requête et envoient des réponses au canal de réponse.
  • Consommateur : Attend les réponses sur le canal de réponse et les gère, en comptant les connexions et le total size.

Avantages des modifications :

  • Concurrence basée sur les canaux : Évite les limites des descripteurs de fichiers en utilisant des canaux pour passer données entre goroutines.
  • Travailleur Pool : Limite le nombre de goroutines à la concurrence maximale spécifiée, évitant ainsi l'épuisement des ressources.
  • Synchronisation : Utilise un sync.WaitGroup pour garantir que toutes les goroutines se terminent avant de quitter, fournissant un sortie propre.
  • Gestion des réponses : Compte les nombre de connexions et la taille totale des réponses pour fournir des mesures sur l'utilisation des ressources.

En suivant ces modifications, vous pouvez efficacement « inonder » votre ordinateur portable avec autant de requêtes HTTP que possible dans les limites de votre ressources du système.

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