Golang Http Client性能验证

golang

一直很好奇golang的net/http的client性能如何,于是我这里做了一次验证,先上代码:

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"sync"
	"sync/atomic"
	"time"
)

var (
	count     uint64
	lastCount uint64
	wg        *sync.WaitGroup
	// Attacker .
	Attacker *http.Client
)

func qps() {
	var origin uint64
	var lastCount uint64
	for {
		if lastCount == 0 {
			origin = atomic.LoadUint64(&count)
		} else {
			origin = lastCount
		}
		time.Sleep(2 * time.Second)
		current := atomic.LoadUint64(&count)
		fmt.Println("qps: ", (current-origin)/2)
		lastCount = current
	}
}

func worker(ch <-chan string) {
	defer wg.Done()
	for url := range ch {
		request, err := http.NewRequest(http.MethodGet, url, nil)
		if err != nil {
			fmt.Println(err.Error())
			continue
		}
		response, err := Attacker.Do(request)
		atomic.AddUint64(&count, 1)
		if err != nil {
			fmt.Println(err.Error())
			continue
		}
		readBody(response)
	}
}

func readBody(r *http.Response) {
	defer r.Body.Close()
	_, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err.Error())
	}
}

func init() {
	Attacker = &http.Client{
		Transport: &http.Transport{
			DisableKeepAlives:   false,
			MaxIdleConns:        400,
			MaxIdleConnsPerHost: 400,
		},
		Timeout: 30 * time.Second,
	}

	wg = &sync.WaitGroup{}
}

func main() {
	var url string
	var workers int
	var total int

	flag.StringVar(&url, "url", "http://localhost:8080/", "url link")
	flag.IntVar(&workers, "workers", 20, "worker number")
	flag.IntVar(&total, "total", 10000, "total number")
	flag.Parse()

	c := make(chan string)
	go func(ch chan<- string, n int) {
		for i := 0; i < n; i++ {
			ch <- url
		}
	}(c, total)

	for i := 0; i < workers; i++ {
		wg.Add(1)
		go worker(c)
	}
	go qps()
	fmt.Println("attacking")
	wg.Wait()
}

服务端实现:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello")
    })
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

使用wrt压测的结果:

./wrk/wrk -t20 -c400 -d30s http://alpha-001:8080/
Running 30s test @ http://alpha-001:8080/
  20 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.40ms    5.50ms 222.14ms   96.11%
    Req/Sec     2.81k   496.11     7.18k    89.50%
  1676604 requests in 30.04s, 193.47MB read
Requests/sec:  55818.62
Transfer/sec:      6.44MB