HTTP1.1
服务端
func RunH1Server(l net.Listener) {
svr := &http.Server{
Handler: &HTTPServer{},
}
svr.SetKeepAlivesEnabled(true)
svr.Serve(l)
}
func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//fmt.Println(r.Header.Get("User-Agent"))
time.Sleep(10 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}
客户端
func getH1Client() *http.Client {
return &http.Client{
Transport: &http.Transport{
DisableKeepAlives: false,
DisableCompression: false,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
MaxConnsPerHost: 100,
},
}
}
Benchmark 测试
func runHTTP1P(b *testing.B, num int) {
l, _ := net.Listen("tcp", url)
go RunH1Server(l)
defer l.Close()
c := getH1Client()
runtime.GOMAXPROCS(num)
b.ReportAllocs()
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
resp, err := c.Get("http://" + url)
if err != nil {
panic(err)
}
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}
})
}
func BenchmarkH1HTTP_1(b *testing.B) {
runHTTP1P(b, 1)
}
func BenchmarkH1HTTP_10(b *testing.B) {
runHTTP1P(b, 10)
}
func BenchmarkH1HTTP_100(b *testing.B) {
runHTTP1P(b, 100)
}
func BenchmarkH1HTTP_1000(b *testing.B) {
runHTTP1P(b, 1000)
}
测试结果
> go test -v http1.1_test.go -bench=.
goos: windows
goarch: amd64
pkg: github.com/bemyth/go-language-advanced
BenchmarkH1HTTP_1
BenchmarkH1HTTP_1-16 118 10034472 ns/op 4838 B/op 52 allocs/op
BenchmarkH1HTTP_10
BenchmarkH1HTTP_10-16 1174 1009868 ns/op 4862 B/op 51 allocs/op
BenchmarkH1HTTP_100
BenchmarkH1HTTP_100-16 11458 101681 ns/op 4994 B/op 51 allocs/op
BenchmarkH1HTTP_200
BenchmarkH1HTTP_200-16 11628 102002 ns/op 4981 B/op 52 allocs/op
BenchmarkH1HTTP_1000
BenchmarkH1HTTP_1000-16 11418 102651 ns/op 5126 B/op 53 allocs/op
PASS
我们设定服务端处理一次请求需要 10 ms,我们可以得到三个信息
- 根据测试1,单个连接在 1s 内可以执行 100 次请求,符合预期
- 根据测试1,2,3,我们依次增大并行度,单位时间内(1s)内的处理效率与并行度等比例上升
- 根据测试3,4,5由于连接池限制最大为100,即使并行度增加,处理效率也并无提升
所以我们可以得到结论,对于一个稳定的服务器,HTTP1.1 单位时间的处理效率和连接数成正比,需要更高的处理效率就必须不断的增加 TCP 连接。因为 HTTP1.1 的请求遵循 FIFO。
HTTP2.0
服务端
func RunH2Server(l net.Listener) {
svr := &HTTPServer{}
s2 := &http2.Server{}
s1 := http.Server{
TLSConfig: &tls.Config{
InsecureSkipVerify: true,
},
Handler: h2c.NewHandler(svr, s2),
}
s1.Serve(l)
}
func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//fmt.Println(r.Header.Get("User-Agent"))
time.Sleep(10 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}
客户端
func getH2Client() *http.Client {
return &http.Client{
Transport: &http2.Transport{
DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
return net.Dial(network, addr)
},
AllowHTTP: true,
},
CheckRedirect: nil,
Jar: nil,
Timeout: 0,
}
}
Benchmark 测试
func runHTTP2P(b *testing.B, num int) {
l, _ := net.Listen("tcp", url)
go RunH2Server(l)
defer l.Close()
c := getH2Client()
runtime.GOMAXPROCS(num)
b.ReportAllocs()
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
resp, err := c.Get("http://" + url)
if err != nil {
panic(err)
}
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}
})
}
func BenchmarkH2HTTP_1(b *testing.B) {
runHTTP2P(b, 1)
}
func BenchmarkH2HTTP_10(b *testing.B) {
runHTTP2P(b, 10)
}
func BenchmarkH2HTTP_100(b *testing.B) {
runHTTP2P(b, 100)
}
func BenchmarkH2HTTP_200(b *testing.B) {
runHTTP2P(b, 200)
}
func BenchmarkH2HTTP_1000(b *testing.B) {
runHTTP2P(b, 1000)
}
测试结果
> go test -v http2.0_test.go -bench=.
goos: windows
goarch: amd64
pkg: github.com/bemyth/go-language-advanced
BenchmarkH2HTTP_1
testing: BenchmarkH2HTTP_1-16 left GOMAXPROCS set to 1
BenchmarkH2HTTP_1-16 118 10034539 ns/op 6012 B/op 65 allocs/op
BenchmarkH2HTTP_10
testing: BenchmarkH2HTTP_10-16 left GOMAXPROCS set to 10
BenchmarkH2HTTP_10-16 1186 1005127 ns/op 5843 B/op 63 allocs/op
BenchmarkH2HTTP_100
BenchmarkH2HTTP_100-16 11799 101626 ns/op 6001 B/op 63 allocs/op
BenchmarkH2HTTP_200
BenchmarkH2HTTP_200-16 22471 52694 ns/op 6016 B/op 63 allocs/op
BenchmarkH2HTTP_1000
BenchmarkH2HTTP_1000-16 7792 155429 ns/op 6721 B/op 66 allocs/op
testing: BenchmarkH2HTTP_1000-16 left GOMAXPROCS set to 1000
PASS
GO HTTP2.0 我没有找到设置连接池数量的地方,但是在测试中执行
netstat -an|find "8080"
发现连接数量一直是 4 个,同时我们可以看到,仅仅 4 个 TCP 连接,就能在并发达到 200 的时候 1s 内执行 2w 次请求。效率远超 HTTP1.1,且不需要更多的 TCP 连接。
网友评论