So maximieren Sie gleichzeitige HTTP-Anfragen in Go
Viele Programmiersprachen und Frameworks bieten Tools zum Senden von HTTP-Anfragen Bei einer großen Anzahl von Anfragen gleichzeitig ist es wichtig zu verstehen, wie die Parallelität maximiert werden kann, um die Leistung zu optimieren. Dieser Artikel befasst sich mit den Feinheiten der „Maximierung“ gleichzeitiger HTTP-Anfragen in Go und nutzt Goroutinen, um das volle Potenzial der Verarbeitungsfunktionen Ihres Systems freizusetzen.
Das Problem:
Betrachten wir ein Szenario, in dem wir mithilfe mehrerer Goroutinen so schnell wie möglich eine Million HTTP-Anfragen an eine bestimmte URL generieren möchten. Allerdings führte der im ersten Beitrag bereitgestellte Code zu Fehlern, da die Grenzwerte für Dateideskriptoren überschritten wurden. Dies ist ein häufiges Problem, wenn versucht wird, eine große Anzahl gleichzeitiger Anfragen zu bearbeiten.
Die Lösung:
Um die Parallelität effektiv zu maximieren, können wir die Dateideskriptorbeschränkung beheben Verwendung eines gepufferten Kanals als Semaphormechanismus innerhalb eines Worker-Pool-Modells. Hier ist eine Aufschlüsselung der Lösung:
Worker-Pool:
Semaphorkanal:
Dispatcher:
Verbraucher:
Optimierter Code:
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 := &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) }
Dieser verbesserte Code kombiniert die zuvor besprochenen Elemente Erstellen Sie ein hocheffizientes Worker-Pool-basiertes System zum gleichzeitigen Senden einer großen Menge an HTTP-Anfragen. Durch sorgfältige Kontrolle der Anzahl gleichzeitiger Anfragen über den Semaphorkanal können wir Probleme im Zusammenhang mit Dateideskriptorbeschränkungen vermeiden und die Nutzung der Ressourcen unseres Systems maximieren.
Zusammenfassend lässt sich sagen, dass wir durch die Verwendung von Goroutinen, einem Semaphorkanal, einem Worker-Pool und einem dedizierten Verbraucher für die Verarbeitung von Antworten die gleichzeitigen HTTP-Anfragen in Go effektiv „maximieren“ können. Dieser Ansatz ermöglicht es uns, Leistungstests und Stresstests effektiv durchzuführen, unsere Systeme an ihre Grenzen zu bringen und wertvolle Erkenntnisse über ihre Leistungsfähigkeit zu gewinnen.
Das obige ist der detaillierte Inhalt vonWie maximiere ich gleichzeitige HTTP-Anfragen in Go mithilfe von Goroutinen und Worker-Pools?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!