多笔交易请求并没有获得高 RPS

问题描述 投票:0回答:0

我正在尝试编写一个多线程客户端来测试我的服务器。当我使用 2 个 goroutine 时,一切都很好,我得到 50k RPS,我的 CPU 负载是正常的,但是当我创建超过 2 个时,RPS 下降到 3K,但是我的 CPU 负载超过了。虽然当我多次运行我的客户端代码时(例如同时在 3 个控制台上运行相同的代码)我得到了更多的 RPS,比如 80k RPS。

这是我的客户端代码

package main

import (
    "fmt"
    "net/http"
    "os"
    "sync"
    "time"
)

func main() {
    requestURL := fmt.Sprintf("http://localhost:%d/home", 3333)
    var wg sync.WaitGroup
    wg.Add(4)
    req, err := http.NewRequest(http.MethodGet, requestURL, nil)
    if err != nil {
        fmt.Printf("client: could not create request: %s\n", err)
        os.Exit(1)
    }
    for i := 0; i < 4; i++ {
        go func() {
            defer wg.Done()
            client := http.Client{
                Timeout: 30 * time.Second,
            }
            for {
                client.Do(req)
            }
        }()
    }
    wg.Wait()
}

这是我的服务器端代码

package main

import (
    "errors"
    "fmt"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
    "log"
    "net/http"
    "os"
    "sync"
)

// log handling
func openLogFile(path string) (*os.File, error) {
    logFile, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
    if err != nil {
        return nil, err
    }
    return logFile, nil
}

// variables of counter in metric
var okStatusCounter = prometheus.NewCounter(
    prometheus.CounterOpts{
        Name: "ok_request_count",
        Help: "Number of 200",
    },
)

func listener(serverLog *log.Logger) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        //metric 
        okStatusCounter.Inc()
        
        w.WriteHeader(http.StatusOK)
    }
}

func main() {
    //metric
    prometheus.MustRegister(okStatusCounter)

    //log handling
    fileSimpleServerLog, err := openLogFile("simpleServer/simpleServerLog.log")
    if err != nil {
        log.Fatal(err)
    }
    serverLog := log.New(fileSimpleServerLog, "[simple server]", log.LstdFlags|log.Lshortfile|log.Lmicroseconds)

    var wg sync.WaitGroup
    wg.Add(1)

    //server:
    go func() {
        defer wg.Done()
        mux := http.NewServeMux()
        mux.HandleFunc("/home", listener(serverLog))
        mux.Handle("/metrics", promhttp.Handler())
        server := http.Server{
            Addr:    fmt.Sprintf(":%d", 3333),
            Handler: mux,
        }
        if err := server.ListenAndServe(); err != nil {
            if !errors.Is(err, http.ErrServerClosed) {
                serverLog.Printf("error running http server: %s\n", err)
            }
        }
    }()
    wg.Wait()
}

起初我以为 go 可能对所有客户端连接使用一个端口,但是当我用 netstat 检查它时它使用了多个端口。我试图搜索,但我找不到任何合适的答案

我试过 sync.Mutex :

var mu sync.Mutex
...
for i := 0; i < 1000; i++ {
        go func() {
            defer wg.Done()
            client := http.Client{
                //Timeout: 30 * time.Second,
            }
            for {
                mu.Lock()
                _, err := client.Do(req)
                if err != nil {
                    clientLog.Printf("client: error making http request: %s\n", err)
                    os.Exit(1)
                }
                mu.Unlock()
            }
        }()
    }
    wg.Wait()
...

通过上面的更改,我得到 13k RPS,我的 CPU 负载是正常的,但这根本不够

multithreading go http request client
© www.soinside.com 2019 - 2024. All rights reserved.