Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah Saya Boleh Memaksimumkan Permintaan HTTP Serentak dalam Go Dengan Cekap Sambil Mengelakkan Keletihan Sumber Sistem?

Bagaimanakah Saya Boleh Memaksimumkan Permintaan HTTP Serentak dalam Go Dengan Cekap Sambil Mengelakkan Keletihan Sumber Sistem?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-26 01:39:09855semak imbas

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

Maksimum Berkesan Permintaan HTTP Serentak dalam Go

Dalam kod anda, anda cuba menghantar 1 juta permintaan HTTP secara serentak, tetapi menghadapi ralat disebabkan untuk memfailkan had deskriptor. Begini cara untuk 'membanjiri' komputer riba anda dengan berkesan dengan permintaan dalam kekangan sistem:

Kod Diubah Suai Menggunakan Concurrency Berasaskan Saluran:

<br>pakej utama </p>
<p>import (</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")

}

taip struct Respons {

*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.Permintaan, 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)

}

Penjelasan:

  • Penghantar: Mencipta saluran permintaan dan menghantar permintaan HTTP ke ia.
  • Kolam Pekerja: Mencipta kumpulan goroutin yang mengambil permintaan daripada saluran permintaan secara serentak dan menghantar respons kepada saluran respons.
  • Pengguna: Menunggu respons pada saluran respons dan mengendalikannya, mengira sambungan dan jumlahnya saiz.

Faedah Pengubahsuaian:

  • Konkurensi Berasaskan Saluran: Mengelakkan had deskriptor fail dengan menggunakan saluran untuk lulus data antara goroutine.
  • Pekerja Kolam: Mengehadkan bilangan goroutin kepada konkurensi maksimum yang ditentukan, mengelakkan keletihan sumber.
  • Penyegerakan: Menggunakan penyegerakan.WaitGroup untuk memastikan semua gorout lengkap sebelum keluar, memberikan keluar bersih.
  • Respons Pengendalian: Mengira bilangan sambungan dan jumlah saiz respons untuk menyediakan metrik pada penggunaan sumber.

Dengan mengikuti pengubahsuaian ini, anda boleh 'membanjiri' komputer riba anda dengan seberapa banyak permintaan HTTP dengan berkesan mungkin dalam had sumber sistem anda.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Memaksimumkan Permintaan HTTP Serentak dalam Go Dengan Cekap Sambil Mengelakkan Keletihan Sumber Sistem?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn