> 백엔드 개발 > Golang > Go에서 동시 HTTP 요청을 최대화하는 방법은 무엇입니까?

Go에서 동시 HTTP 요청을 최대화하는 방법은 무엇입니까?

Linda Hamilton
풀어 주다: 2024-11-26 15:06:10
원래의
657명이 탐색했습니다.

How to Maximize Concurrent HTTP Requests in Go?

동시 HTTP 요청을 효과적으로 "최대화"하는 방법은 무엇입니까?

Go의 성능을 실험할 때 대량의 HTTP 요청을 동시에 실행하려고 시도하는 동안 제한 사항에 직면할 수 있습니다. . 이 기사에서는 직면한 과제를 탐색하고 최대 동시성을 달성하기 위한 솔루션을 제공합니다.

문제

초기 접근 방식에는 HTTP 요청을 병렬로 보내기 위해 많은 수의 고루틴을 실행하는 것이 포함됩니다. 사용 가능한 모든 CPU. 그러나 파일 설명자 제한으로 인해 오류가 발생합니다.

해결책

이러한 제한을 극복하려면 다음 접근 방식을 고려하십시오.

  • 제한된 동시성을 제어하는 ​​세마포어 채널: 세마포어 역할을 하는 버퍼링된 채널을 구현하여 동시성 수를 제한합니다. 요청. 채널 버퍼 크기를 조정하고 GOMAXPROCS를 조정하면 시스템의 동시성을 최적화할 수 있습니다.
  • 디스패처로 작업자 풀 활용: 요청이 채널에 대기하는 작업자 풀 패턴을 사용합니다. . 디스패처는 채널을 채우고 작업자 풀은 한 번에 하나씩 요청을 처리합니다. 이 접근 방식을 사용하면 동시 요청의 최대 수가 유지됩니다.
  • 전용 소비자 고루틴을 활용하여 응답을 처리합니다. 요청 처리 차단을 방지하려면 전용 고루틴을 사용하여 작업자의 응답을 소비합니다. 수영장. 이렇게 하면 지속적인 요청 실행이 보장되어 시스템이 더 많은 동시 요청을 처리할 수 있습니다.

최적화된 코드

다음은 이러한 최적화를 통합하는 수정된 코드 버전입니다.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿