Go のパフォーマンスを実験するときに、大量の HTTP リクエストを同時に実行しようとすると制限に遭遇する可能性があります。 。この記事では、直面する課題を検討し、最大の同時実行性を達成するためのソリューションを提供します。
最初のアプローチでは、HTTP リクエストを並行して送信するために多数のゴルーチンを起動し、それらのゴルーチンが利用されることを期待します。利用可能なすべての CPU。ただし、ファイル記述子の制限によりエラーが発生します。
これらの制限を克服するには、次のアプローチを検討してください。
これらの最適化を組み込んだコードの修正バージョンを次に示します。
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) }
同時実行変数を調整して結果を観察することで、システムに最適な同時実行レベル、つまり「最大化」を決定できます。同時 HTTP リクエストの処理能力。
以上がGo で同時 HTTP リクエストを最大化するには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。