Rumah >pembangunan bahagian belakang >Golang >Bolehkah Komputer Riba Saya Mengendalikan Sejuta Permintaan HTTP Serentak Menggunakan Go?

Bolehkah Komputer Riba Saya Mengendalikan Sejuta Permintaan HTTP Serentak Menggunakan Go?

Linda Hamilton
Linda Hamiltonasal
2024-12-01 17:01:08944semak imbas

Can My Laptop Handle One Million Concurrent HTTP Requests Using Go?

Bolehkah Komputer Riba Anda Mengendalikan Sejuta Permintaan HTTP Serentak?

Bayangkan menghantar 1,000,000 permintaan HTTP serentak ke perkhidmatan API REST, menolak had komputer anda untuk memaksimumkan konkurensi. Walaupun alatan wujud untuk tugasan ini, mari kita mendalami cara melakukannya dalam Go menggunakan goroutines.

package main

import (
    "fmt"
    "net/http"
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU()) // Use all available CPU cores
    transport := &http.Transport{}        // Create an HTTP transport

    for i := 0; i < 1000000; i++ {
        go func() { // Start a goroutine for each HTTP request
            req, _ := http.NewRequest("GET", "http://myapi.com", nil)
            req.Header.Set("User-Agent", "custom-agent")
            req.SetBasicAuth("xxx", "xxx")

            resp, err := transport.RoundTrip(req)
            if err != nil {
                panic("HTTP request failed.")
            }
            defer resp.Body.Close()

            if resp.StatusCode != 302 {
                panic("Unexpected response returned.")
            }

            location := resp.Header.Get("Location")
            if location == "" {
                panic("No location header returned.")
            }

            fmt.Println("Location Header Value:", location)
        }()
    }

    time.Sleep(60 * time.Second) // Sleep for 60 seconds
}

Tetapi Tunggu, Ada Masalah!

Menjalankan skrip ini mengakibatkan ralat disebabkan oleh had deskriptor fail. Sistem ini tidak boleh mengendalikan begitu banyak sambungan serentak.

Penyelesaian yang Diperbaiki

Untuk mengatasi batasan ini, kita perlu menggunakan pendekatan yang lebih canggih.

Menggunakan Kolam Penghantar dan Pekerja

Ini penyelesaian melibatkan mencipta goroutine penghantar yang menolak permintaan ke saluran. Kumpulan goroutine pekerja menarik permintaan daripada saluran, memprosesnya dan menghantarnya ke saluran respons. Sebuah goroutine pengguna kemudian memproses respons.

// Dispatcher function
func dispatcher(reqChan chan *http.Request, reqs int) {
    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
    }
}

// Worker function
func worker(t *http.Transport, reqChan chan *http.Request, respChan chan Response) {
    for req := range reqChan {
        resp, err := t.RoundTrip(req)
        r := Response{resp, err}
        respChan <- r
    }
}

// Consumer function
func consumer(respChan chan Response, reqs int) (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
}

Hasil

Menjalankan skrip yang dipertingkat ini menjana hasil yang mengagumkan, seperti:

Sambungan: 1000000

Serentak: 200

Jumlah saiz: 15000000 bait

Jumlah masa: 38m20.3012317s

Purata masa: 2.280131ms


Mengoptimumkan Prestasi

Walau bagaimanapun, mengubah bilangan permintaan serentak dan jumlah permintaan akan membantu anda had sistem anda dan uji tekanan keupayaannya. Ingat, ini adalah ujian yang melampau dan boleh menggunakan sumber sistem dengan pantas.

Atas ialah kandungan terperinci Bolehkah Komputer Riba Saya Mengendalikan Sejuta Permintaan HTTP Serentak Menggunakan Go?. 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