对比 Gin\net/http\Hz 三种web 框架

491 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

最近在研究网站的一些高并发操作(base 语言用的是Go,所以这里选择的Go框架比较多)。所以就选择了这两种种大家比较常用的web框架和一种字节开源的web 框架。我们可以来对比一下并发时候他们的数据。

框架选择

  • Gin(Go)

github.com/gin-gonic/g…

  • net/http (Go)

pkg.go.dev/net/http

  • Hz (Go)

github.com/cloudwego/h…

  • Flask (Python)

测试工具🔧

关于测试工具的选择

  • ab

通过ab发送请求模拟多个访问者同时对某一URL地址进行访问,可以得到每秒传送字节数、每秒处理请求数、每请求处理时间等统计数据。

命令格式 ab [options] [http://]hostname[:port]/path

参数:

-n requests 总请求数
-c concurrency 一次产生的请求数,可以理解为并发数
-t timelimit 测试所进行的最大秒数, 可以当做请求的超时时间
-p postfile 包含了需要POST的数据的文件
-T content-type POST数据所使用的Content-type头信息
  • wrk

wrk是一款开源的HTTP性能测试工具,它和上面提到的ab同属于HTTP性能测试工具,它比ab功能更加强大,可以通过编写lua脚本来支持更加复杂的测试场景。

  • go-wrk

go-wrk是Go语言版本的wrk,Windows同学可以使用它来测试,使用如下命令来安装go-wrk

这里我们选择比较轻量级的 ab进行测试

测试

gin

代码

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	r := gin.Default()
	number := 0
	r.GET("/ping", func(context *gin.Context) {
		number += 1
		fmt.Printf("%d\n",number)
		context.String(http.StatusOK,"hello!")
	})
	r.POST("/add", func(c *gin.Context) {
		c.String(http.StatusOK,"hi")
	})
	r.Run("0.0.0.0:5002")
}

s ab -n10000 -c100 -s 30 http://127.0.0.1:5002/ping

This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            5002

Document Path:          /ping
Document Length:        6 bytes

Concurrency Level:      100
Time taken for tests:   19.234 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1220000 bytes
HTML transferred:       60000 bytes
Requests per second:    519.92 [#/sec] (mean)
Time per request:       192.337 [ms] (mean)
Time per request:       1.923 [ms] (mean, across all concurrent requests)
Transfer rate:          61.94 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   82  21.4     78     154
Processing:    31  109  29.3    105     285
Waiting:        4   80  26.7     79     217
Total:         78  191  38.0    184     384

Percentage of the requests served within a certain time (ms)
  50%    184
  66%    203
  75%    217
  80%    225
  90%    243
  95%    259
  98%    279
  99%    298
 100%    384 (longest request)

Hz


package main

import (
	"context"
	"fmt"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	number := 0
	h := server.Default(
		server.WithHostPorts("0.0.0.0:5006"),
	)

	h.POST("/ping", func(c context.Context, ctx *app.RequestContext) {

		number += 1
		ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"})
		fmt.Println(number)
	})

	h.Spin()
}

➜ s ab -n10000 -c100 -s 30 http://127.0.0.1:5006/ping


This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        hertz
Server Hostname:        127.0.0.1
Server Port:            5006

Document Path:          /ping
Document Length:        18 bytes

Concurrency Level:      100
Time taken for tests:   15.339 seconds
Complete requests:      10000
Failed requests:        0
Non-2xx responses:      10000
Total transferred:      1700000 bytes
HTML transferred:       180000 bytes
Requests per second:    651.91 [#/sec] (mean)
Time per request:       153.395 [ms] (mean)
Time per request:       1.534 [ms] (mean, across all concurrent requests)
Transfer rate:          108.23 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   70  16.1     69     136
Processing:    30   82  21.5     79     191
Waiting:        0   57  21.1     55     150
Total:         92  152  18.8    148     278

Percentage of the requests served within a certain time (ms)
  50%    148
  66%    156
  75%    162
  80%    165
  90%    177
  95%    189
  98%    204
  99%    212
 100%    278 (longest request)

net/http

package main

import (
   "fmt"
   "net/http"
)

func hello(w http.ResponseWriter, req *http.Request) {

   fmt.Fprintf(w, "hello\n")
}

func headers(w http.ResponseWriter, req *http.Request) {

   for name, headers := range req.Header {
       for _, h := range headers {
           fmt.Fprintf(w, "%v: %v\n", name, h)
       }
   }
}

func main() {

   http.HandleFunc("/hello", hello)
   http.HandleFunc("/headers", headers)

   http.ListenAndServe(":8090", nil)
}

➜ s ab -n10000 -c100 -s 30 http://127.0.0.1:8090/hello


This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            8090

Document Path:          /hello
Document Length:        6 bytes

Concurrency Level:      100
Time taken for tests:   16.576 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1220000 bytes
HTML transferred:       60000 bytes
Requests per second:    603.27 [#/sec] (mean)
Time per request:       165.764 [ms] (mean)
Time per request:       1.658 [ms] (mean, across all concurrent requests)
Transfer rate:          71.87 [Kbytes/sec] received

Connection Times (ms)
             min  mean[+/-sd] median   max
Connect:        1   78  19.1     76     157
Processing:    38   87  22.7     84     212
Waiting:        4   60  22.0     56     182
Total:         87  164  25.2    158     303

Percentage of the requests served within a certain time (ms)
 50%    158
 66%    171
 75%    180
 80%    186
 90%    201
 95%    215
 98%    229
 99%    235
100%    303 (longest request)

结果

对比结果很明显 从Time taken for tests参数来看,性能优势 Hz > net/http > Gin