首頁 > 後端開發 > Golang > 主體

Go中如何有效率最大化並發HTTP請求,同時避免系統資源耗盡?

Mary-Kate Olsen
發布: 2024-11-26 01:39:09
原創
831 人瀏覽過

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

Go 中並發HTTP 請求的有效最大化

在您的程式碼中,您嘗試並發100 萬個HTTP 請求,但遇到了錯誤文件描述符限制。以下是如何在系統限制內用請求有效地「淹沒」您的筆記型電腦:

使用基於通道的並發修改代碼:

<br>package main <p>導入(</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")
登入後複製

func init() {

)

func init() {
*http.Response
err error
登入後複製
)

func init() {

)

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

}

類型回應結構{

t := &amp;http.Transport{}
for i := 0; i < max; i++ {
    go worker(t, reqChan, respChan, wg)
}
登入後複製
}

func 調度程式(reqChan chan *http.Request) {

}

}
for req := range reqChan {
    resp, err := t.RoundTrip(req)
    r := Response{resp, err}
    respChan <- r
}
wg.Done()
登入後複製
}

}

}

}

}
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
登入後複製
}

}

}

}

}
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)
登入後複製

func workerPool(reqChan chan
http.Request,respChan chan 回應,wg

sync.WaitGroup) {

http}

    func worker(t
  • http}func worker(t http}
  • >http.Request, respChan chan Response, wg *同步.WaitGroup) {
  • }
  • func Consumer(respChan chan Response) (int64, int64) {

func main() {

}
  • 說明:
  • 調度員:
  • 建立請求通道並將HTTP請求發送到
  • 工作池:
  • 建立一個 goroutine 池,這些協程同時消費來自請求通道的請求並向回應通道發送回應。
  • 消費者:
等待回應通道上的回應並處理它們,計算連接數和總數

修改的好處:基於通道的並發:透過使用通道傳遞來避免檔案描述符限制goroutine 之間的資料。 Worker池: 將 goroutine 數量限制為指定的最大並發數,防止資源耗盡。 同步: 使用sync.WaitGroup 確保所有 goroutine 在退出前完成,提供乾淨退出。 回應處理: 計算連接和回應的總大小,以提供有關資源使用情況的指標。 透過進行這些修改,您可以在系統資源的限制內使用盡可能多的 HTTP 請求有效地「淹沒」您的筆記型電腦.

以上是Go中如何有效率最大化並發HTTP請求,同時避免系統資源耗盡?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板