Heim > Backend-Entwicklung > Golang > Wie kann ich gleichzeitige HTTP-Anfragen in Go effizient maximieren und gleichzeitig eine Erschöpfung der Systemressourcen vermeiden?

Wie kann ich gleichzeitige HTTP-Anfragen in Go effizient maximieren und gleichzeitig eine Erschöpfung der Systemressourcen vermeiden?

Mary-Kate Olsen
Freigeben: 2024-11-26 01:39:09
Original
926 Leute haben es durchsucht

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

Effektive Maximierung gleichzeitiger HTTP-Anfragen in Go

In Ihrem Code haben Sie versucht, 1 Million HTTP-Anfragen gleichzeitig zu senden, sind dabei aber auf Fehler gestoßen zu Dateideskriptor-Einschränkungen. So können Sie Ihren Laptop innerhalb der Systembeschränkungen effektiv mit Anfragen „überfluten“:

Geänderter Code mit kanalbasierter Parallelität:

<br>Pakethaupt </p>
<p>importieren (</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">"flag"
"fmt"
"log"
"net/http"
"runtime"
"sync"
"time"
Nach dem Login kopieren

)

var (

reqs int
max  int
Nach dem Login kopieren

)

func init() {

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

}

Typ Antwortstruktur {

*http.Response
err error
Nach dem Login kopieren

}

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
}
Nach dem Login kopieren

}

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)
}
Nach dem Login kopieren

}

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()
Nach dem Login kopieren

}

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
Nach dem Login kopieren

}

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)
Nach dem Login kopieren

}

Erklärung:

  • Disponent: Erstellt einen Anfragekanal und sendet HTTP-Anfragen an ihn.
  • Worker Pool: Erstellt einen Pool von Goroutinen, die gleichzeitig Anfragen vom Anfragekanal konsumieren und Antworten an den Antwortkanal senden.
  • Verbraucher: Wartet auf Antworten auf dem Antwortkanal und verarbeitet diese , wobei die Verbindungen und die Gesamtgröße gezählt werden.

Vorteile von Änderungen:

  • Kanalbasierte Parallelität: Vermeidet Dateideskriptorbeschränkungen, indem Kanäle zum Übergeben von Daten zwischen Goroutinen verwendet werden.
  • Worker-Pool: Begrenzt die Anzahl der Goroutinen auf die angegebene maximale Parallelität und spart so Ressourcen Erschöpfung.
  • Synchronisation: Verwendet eine sync.WaitGroup, um sicherzustellen, dass alle Goroutinen vor dem Beenden abgeschlossen werden, um einen sauberen Ausgang zu gewährleisten.
  • Antwortverarbeitung: Zählt die Anzahl der Verbindungen und die Gesamtgröße der Antworten, um Metriken zur Ressource bereitzustellen Nutzung.

Indem Sie diese Änderungen befolgen, können Sie Ihren Laptop effektiv mit so vielen HTTP-Anfragen wie möglich im Rahmen der Einschränkungen Ihrer Systemressourcen „überfluten“.

Das obige ist der detaillierte Inhalt vonWie kann ich gleichzeitige HTTP-Anfragen in Go effizient maximieren und gleichzeitig eine Erschöpfung der Systemressourcen vermeiden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage