ホームページ > バックエンド開発 > Golang > システム リソースの枯渇を回避しながら、Go で同時 HTTP リクエストを効率的に最大化するにはどうすればよいですか?

システム リソースの枯渇を回避しながら、Go で同時 HTTP リクエストを効率的に最大化するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-11-26 01:39:09
オリジナル
870 人が閲覧しました

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

Go での同時 HTTP リクエストの効果的な最大化

コードでは、100 万の HTTP リクエストを同時に送信しようとしましたが、次の理由によるエラーが発生しました。ファイル記述子の制限に影響します。システム制約内でラップトップにリクエストを効果的に「フラッディング」する方法は次のとおりです:

チャネルベースの同時実行性を使用した変更コード:

<br>package main </p>
<p>インポート(</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"
ログイン後にコピー

)

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 応答構造体{

*http.Response
err error
ログイン後にコピー

}

func ディスパッチャー(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.リクエスト、respChan chan レスポンス、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 *同期.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)
ログイン後にコピー

}

説明:

  • ディスパッチャー:リクエストチャネルを作成し、HTTPリクエストを送信します。 it.
  • ワーカー プール: 要求チャネルからの要求を同時に消費し、応答チャネルに応答を送信するゴルーチンのプールを作成します。
  • コンシューマー: 応答チャネルで応答を待って処理し、接続数と合計をカウントします。 size.

変更の利点:

  • チャネルベースの同時実行: 渡すチャネルを使用することで、ファイル記述子の制限を回避します。間のデータgoroutines.
  • ワーカー プール: ゴルーチンの数を指定された最大同時実行性に制限し、リソースの枯渇を防ぎます。
  • 同期: 同期を使用します。 WaitGroup は、すべてのゴルーチンが終了する前に完了することを確認し、クリーンな状態を提供します。 exit.
  • 応答処理: 接続数と応答の合計サイズをカウントして、リソース使用量に関するメトリクスを提供します。

これらの変更に従うことで、システムのリソースの制限内で、できるだけ多くの HTTP リクエストをラップトップに効果的に「フラッディング」することができます。

以上がシステム リソースの枯渇を回避しながら、Go で同時 HTTP リクエストを効率的に最大化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート