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
Mary-Kate OlsenOriginal
2024-11-26 01:39:09850Durchsuche

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>
<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")

}

Typ Antwortstruktur {

*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()

}

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, 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)

}

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!

Stellungnahme:
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