golang主流高性能web框架性能测试
测试目的
由于K8s缘故涉猎go语言,发现golang的web框架很多,都号称高性能标杆;之前一直致力于c++高性能服务端框架研究,出于好奇,想单从性能层面客观比较一下go的众多web框架,另一方面也希望看看c++的实现与go语言实现之间究竟存在多大差异。
高性能服务框架评估指标很多,但一般来讲吞吐量与QPS是关键考量指标,吞吐量衡量带宽利用率,QPS主要考验框架调度性能(几乎所有可称之为“高性能”的服务框架都没有吞吐量问题,毕竟网络瓶颈很轻易就达到了)。由于是框架本身QPS测试,为了屏蔽http协议实现差异选择最精简的协议头(协议处理一般不会有锁,为cpu密集型),因此要求请求/返回报文尽可能小,本文测试基于http协议,返回空报文。
为了实现测试的第二个目的,特将一个自撸的c++服务框架作为c++实现的”砖头”,加入到对比测试中。此框架尚未开源,其高性能特性保障体现在如下设计上:
- 跨平台实现socket多路复用,支持:poll、epoll、kqueue、port、select、IOCP等模型
- 采用lock-free算法
- 线程池设计
- socket连接池
- 多级任务队列
……
PS:
好吧,这样一来貌似更接近测试socket服务框架调度性能…… 不要纠结keep-alive,因为wrk使用HTTP/1.1,默认都是keep-alive的
测试环境
环境设置
ulimit -n 2000
压测工具
wrk
由于环境限制,只能wrk客户端和待测试服务端在一台机器上运行
c++自研框架
- 启动脚本:(最大2000个并发连接,2个线程处理,http端口8080)
./proxy_server -i2000 -o2000 -w2 -x8080 - 如有条件测试linux系统可自行下载服务端(选择对应平台的包):github.com/lazy-luo/smarGate
- http返回报文:
$ curl -i http://localhost:8080/ HTTP/1.1 200 OK Content-Length: 0 Connection: keep-alive
- 压测结果:
$wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 13.03ms 3.80ms 100.73ms 86.97% Req/Sec 9.43k 1.64k 39.35k 88.23% 7509655 requests in 1.67m, 444.03MB read Socket errors: connect 0, read 794, write 2, timeout 0 Requests/sec: 75018.11 Transfer/sec: 4.44MB
- 资源占用:
go-restful框架:
- main_go-restful.go
package main import ( "github.com/emicklei/go-restful" "net/http" ) func main(){ ws := new(restful.WebService) ws.Route(ws.GET("/").To(hello)) restful.Add(ws) http.ListenAndServe(":8080",nil) } func hello(req *restful.Request,resp *restful.Response){ resp.Write([]byte("")) }
- http返回报文:
$curl -i http://localhost:8080/ HTTP/1.1 200 OK Date: Mon, 21 Oct 2019 03:54:27 GMT Content-Length: 0
- 压测结果:
$wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 19.72ms 10.57ms 331.94ms 87.67% Req/Sec 6.52k 1.24k 23.75k 80.42% 5180908 requests in 1.67m, 370.57MB read Socket errors: connect 0, read 844, write 3, timeout 0 Requests/sec: 51757.61 Transfer/sec: 3.70MB
- 资源占用:
go-echo框架:
- main_go-echo.go
package main import ( "net/http" "github.com/labstack/echo" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "") }) e.Logger.Fatal(e.Start(":8080")) }
- http返回报文:
$ curl -i http://localhost:8080/ HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Date: Mon, 21 Oct 2019 04:09:24 GMT Content-Length: 0
- 压测结果:
$ wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 17.32ms 8.19ms 252.60ms 90.70% Req/Sec 7.52k 1.35k 39.96k 80.55% 5974370 requests in 1.67m, 660.92MB read Socket errors: connect 0, read 431, write 67, timeout 0 Requests/sec: 59686.09 Transfer/sec: 6.60MB
- 资源占用:
go-iris框架:
- main_go-iris.go
package main import( "time" "github.com/kataras/iris" "github.com/kataras/iris/cache" ) func main(){ app := iris.New() app.Logger().SetLevel("error") app.Get("/",cache.Handler(10*time.Second),writeMarkdown) app.Run(iris.Addr(":8080")) } func writeMarkdown(ctx iris.Context){ ctx.Markdown([]byte("")) }
- http返回报文:
$ curl -i http://localhost:8080/ HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Date: Mon, 21 Oct 2019 04:11:59 GMT Content-Length: 0
- 压测结果:
$ wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 22.03ms 7.99ms 140.47ms 84.58% Req/Sec 5.79k 775.23 19.31k 80.35% 4608572 requests in 1.67m, 505.43MB read Socket errors: connect 0, read 726, write 22, timeout 0 Requests/sec: 46041.23 Transfer/sec: 5.05MB
- 资源占用:
go-gin框架
- main_go-gin.go
package main import ( "fmt" "net/http" "log" "github.com/julienschmidt/httprouter" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "") } func main() { router := httprouter.New() router.GET("/", Index) log.Fatal(http.ListenAndServe(":8080", router)) }
- http返回报文:
$ curl -i http://localhost:8080/ HTTP/1.1 200 OK Date: Mon, 21 Oct 2019 04:15:33 GMT Content-Length: 0
- 压测结果:
$ wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 16.71ms 7.72ms 268.45ms 87.79% Req/Sec 7.71k 1.58k 21.27k 82.12% 6130281 requests in 1.67m, 438.47MB read Socket errors: connect 0, read 693, write 36, timeout 0 Requests/sec: 61243.74 Transfer/sec: 4.38MB
- 资源占用:
go-chi框架:
- main_go-chi.go
package main import ( "net/http" "github.com/go-chi/chi" ) func main() { r := chi.NewRouter() r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("")) }) http.ListenAndServe(":8080", r) }
- http返回报文:
$ curl -i http://localhost:8080/ HTTP/1.1 200 OK Date: Mon, 21 Oct 2019 04:18:42 GMT Content-Length: 0
- 压测结果:
$ wrk -d 100s -c 1024 -t 8 http://localhost:8080/ Running 2m test @ http://localhost:8080/ 8 threads and 1024 connections Thread Stats Avg Stdev Max +/- Stdev Latency 17.17ms 8.47ms 253.47ms 90.07% Req/Sec 7.65k 1.42k 26.08k 79.76% 6071695 requests in 1.67m, 434.28MB read Socket errors: connect 0, read 110, write 2, timeout 0 Requests/sec: 60658.49 Transfer/sec: 4.34MB
- 资源占用:
结论:
- | cpu-free | mem-usage | qps |
---|---|---|---|
c++ | 15%-20% | 6M | 75018.11 |
go-gin | 0%-1.5% | 28M | 61243.74 |
go-chi | 0%-1% | 28M | 60658.49 |
go-echo | 0%-0.5% | 28M | 59686.09 |
go-restful | 0%-0.5% | 34M | 51757.61 |
go-iris | 0%-1% | 37M | 46041.23 |
- go语言web框架中gin、chi、echo性能相当,gin略显优势,iris实测效果不佳;
- go语言与c++语言网络框架比较还是存在一定性能差距,但不是决定性的;
- go语言整体资源耗用大,c++足够轻量高效;
- go语言真的很易用且简洁!!就是三方依赖太多 ,拿来主义,问题排查那是相当酸爽...... 当然,随着依赖包升级你会一直爽 :)
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
高级渗透测试对公司网站漏洞检测详情
天气逐渐变凉,但渗透测试的热情温度感觉不到凉,因为有我们的存在公开分享渗透实战经验过程,才会让这个秋冬变得不再冷,近期有反映在各个环境下的目录解析漏洞的检测方法,那么本节由我们高级渗透架构师来详细的讲解平常用到的web环境检测点和网站漏洞防护办法。 3.14.1. IIS 3.14.1.1. IIS 6.0 后缀解析 /xx.asp;.jpg目录解析 /xx.asp/xx.jpg (xx.asp目录下任意解析)默认解析 xx.asa xx.cer xx.cdxPROPFIND 栈溢出漏洞PUT漏洞 WebDAV任意文件上传3.14.1.2. IIS 7.0-7.5 / Nginx <= 0.8.37 在Fast-CGI开启状态下,在文件路径后加上 /xx.php ,则 xx.jpg/xx.php 会被解析为php文件 3.14.1.3. 其他 在支持NTFS 8.3文件格式时,可利用短文件名猜解目录文件 3.14.2. Nginx 3.14.2.1. Fast-CGI关闭 在Fast-CGI关闭的情况下, Nginx 仍然存在解析漏洞:在文件路径(xx.jpg)后面加上 %00....
- 下一篇
C++并发编程(C++11到C++17)
为什么要并发编程 大型的软件项目常常包含非常多的任务需要处理。例如:对于大量数据的数据流处理,或者是包含复杂GUI界面的应用程序。如果将所有的任务都以串行的方式执行,则整个系统的效率将会非常低下,应用程序的用户体验会非常的差。 另一方面,自上个世纪六七十年代英特尔创始人之一 Gordon Moore 提出 摩尔定义 以来,CPU频率以每18个月翻一番的指数速度增长。但这一增长在最近的十年已经基本停滞,大家会发现曾经有过一段时间CPU的频率从3G到达4G,但在这之后就停滞不前了。因此最近的新款CPU也基本上都是3G左右的频率。相应的,CPU以更多核的形式在增长。目前的Intel i7有8核的版本,Xeon处理器达到了28核。并且,最近几年手机上使用的CPU也基本上是4核或者8核的了。 由此,掌握并发编程技术,利用多处理器来提升软件项目的性
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2全家桶,快速入门学习开发网站教程