>  기사  >  백엔드 개발  >  시스템 리소스 고갈을 피하면서 Go에서 동시 HTTP 요청을 효율적으로 최대화하려면 어떻게 해야 합니까?

시스템 리소스 고갈을 피하면서 Go에서 동시 HTTP 요청을 효율적으로 최대화하려면 어떻게 해야 합니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-26 01:39:09824검색

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

Go에서 동시 HTTP 요청의 효과적인 최대화

코드에서 1백만 개의 HTTP 요청을 동시에 전송하려고 시도했지만 오류가 발생했습니다. 파일 설명자 제한 사항. 시스템 제약 내에서 노트북에 요청이 효과적으로 '넘치는' 방법은 다음과 같습니다.

채널 기반 동시성을 사용하여 수정된 코드:

<br>package main </p>
<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")

}

응답 구조체 유형 {

*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.Request, respChan chan 응답, wg sync.WaitGroup) {

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

}

func 작업자(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 소비자(respChan chan 응답) (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.

수정의 이점:

  • 채널 기반 동시성: 전달하는 채널을 사용하여 파일 설명자 제한을 피합니다. 사이의 데이터 고루틴.
  • 작업자 풀: 고루틴 수를 지정된 최대 동시성으로 제한하여 리소스 고갈을 방지합니다.
  • 동기화: 동기화를 사용합니다. WaitGroup은 종료하기 전에 모든 고루틴이 완료되었는지 확인하여 깨끗한 결과를 제공합니다. 종료.
  • 응답 처리: 연결 수와 총 응답 크기를 계산하여 리소스 사용량에 대한 지표를 제공합니다.

이러한 수정 사항을 따르면 시스템 리소스 제한 내에서 최대한 많은 HTTP 요청으로 노트북을 효과적으로 '넘치게' 할 수 있습니다.

위 내용은 시스템 리소스 고갈을 피하면서 Go에서 동시 HTTP 요청을 효율적으로 최대화하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.