Kirill
Kirill

Reputation: 8341

Can't overcome 4000 RPS treshold on localhost HTTP Golang server

I tried to measure the bandwidth of Go default HTTP server implementation on my local machine. The server is just accepting any HTTP request, increments the counter using sync.atomic and send 200 OK response. Also, the server collects amount of requests every second, prints it and resets counter to zero:

type hand struct {
    cnt int32
}

func (h *hand) ServeHTTP(rsp http.ResponseWriter, req *http.Request) {
    atomic.AddInt32(&h.cnt, 1)
    rsp.WriteHeader(200)
    if req.Body != nil {
        req.Body.Close()
    }
}

func main() {
    h := new(hand)
    s := &http.Server{
        Addr:    ":8080",
        Handler: h,
    }
    ticker := time.NewTicker(1 * time.Second)
    go func() {
        for tick := range ticker.C {
            val := atomic.SwapInt32(&h.cnt, 0)
            fmt.Printf("(%v) %d RPS\n", tick, val)
        }
    }()
    log.Fatal(s.ListenAndServe())
}

The target client is trying to send 100000 GET requests simultaneously:

const total = 100000

func main() {
    var r int32
    var rsp int32
    r = total
    rsp = r
    for r > 0 {
        go func() {
            p, err := http.Get("http://localhost:8080")
            atomic.AddInt32(&rsp, -1)
            if err != nil {
                fmt.Printf("error: %s\n", err)
                return
            }
            if p.StatusCode != 200 {
                fmt.Printf("status %d\n", p.StatusCode)
            }
        }()
        r--

    }
    for {
        x := atomic.LoadInt32(&rsp)
        fmt.Printf("sent : %d\n", total-x)
        if x == 0 {
            return
        }
        time.Sleep(1 * time.Second)
    }
}

I'm using Linux machine with 5.3.2-gentoo kernel. I changed ulimits (both soft and hard) of nofile to 100000. When I run this tests, all other user applications were stopped.

I'm not expecting to get accurate results, but just need to know the level of this threshold, something like X000 or X0000 or X00000.

But the server can't process more than 4000 requests per second, it's looking too low:

# removed timestamps
0 RPS
0 RPS
0 RPS
3953 RPS
3302 RPS
387 RPS
37 RPS
1712 RPS

How can I raise the bandwidth of HTTP server? Or maybe there is an issue with my testing method or local configuration?

Upvotes: 0

Views: 1362

Answers (1)

Kirill
Kirill

Reputation: 8341

The problem was in testing method:

  1. It's not correct to run client and server on the same machine, the target server should be located at dedicated host, the network between target and client should be fast enough
  2. Custom scripts for network testing is not an option: for simple cases wrk can be used, for more complex scenarios Jmetr or other frameworks

When I tested this server on dedicated host using wrk it shows 285900.73 RPS.

Upvotes: 1

Related Questions