fasthttp性能真的比标准库http包好很多吗?一文告诉你真相!

文章通过性能测试对比了Go的fasthttp和标准库http在web server中的表现。尽管fasthttp声称性能更高,但在特定场景下,实际测试结果显示fasthttp仅比http性能提升30%~70%,并未达到预期的十倍差距。测试表明,fasthttp的goroutine复用策略在长连接和饱和请求场景下效果不明显,反而可能导致Go runtime调度开销增加。优化途径可能包括利用多路复用技术减少goroutine数量的增长。
摘要由CSDN通过智能技术生成

1. 背景

Go初学者学习Go时,在编写了经典的“hello, world”程序之后,可能会迫不及待的体验一下Go强大的标准库,比如:用几行代码写一个像下面示例这样拥有完整功能的web server:

// 来自https://tip.golang.org/pkg/net/http/#example_ListenAndServe
package main

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

func main() {
   
	helloHandler := func(w http.ResponseWriter, req *http.Request) {
   
		io.WriteString(w, "Hello, world!\n")
	}
	http.HandleFunc("/hello", helloHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}


go net/http包是一个比较均衡的通用实现,能满足大多数gopher 90%以上场景的需要,并且具有如下优点:

  • 标准库包,无需引入任何第三方依赖;
  • 对http规范的满足度较好;
  • 无需做任何优化,即可获得相对较高的性能;
  • 支持HTTP代理;
  • 支持HTTPS;
  • 无缝支持HTTP/2。

不过也正是因为http包的“均衡”通用实现,在一些对性能要求严格的领域,net/http的性能可能无法胜任,也没有太多的调优空间。这时我们会将眼光转移到其他第三方的http服务端框架实现上。

而在第三方http服务端框架中,一个“行如其名”的框架fasthttp被提及和采纳的较多,fasthttp官网宣称其性能是net/http的十倍(基于go test benchmark的测试结果)。

fasthttp采用了许多性能优化上的最佳实践,尤其是在内存对象的重用上,大量使用sync.Pool以降低对Go GC的压力。

那么在真实环境中,到底fasthttp能比net/http快多少呢?恰好手里有两台性能还不错的服务器可用,在本文中我们就在这个真实环境下看看他们的实际性能。

2. 性能测试

我们分别用net/http和fasthttp实现两个几乎“零业务”的被测程序:

  • nethttp:
// github.com/bigwhite/experiments/blob/master/http-benchmark/nethttp/main.go
package main

import (
	_ "expvar"
	"log"
	"net/http"
	_ "net/http/pprof"
	"runtime"
	"time"
)

func main() {
   
	go func() {
   
		for {
   
			log.Println("当前routine数量:", runtime.NumGoroutine())
			time.Sleep(time.Second)
		}
	}()

	http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   
		w.Write([]byte("Hello, Go!"))
	}))

	log.Fatal(http.ListenAndServe(":8080", nil))
}

  • fasthttp:
// github.com/bigwhite/experiments/blob/master/http-benchmark/fasthttp/main.go

package main

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"time"

	_ "expvar"

	_ "net/http/pprof"

	"github.com/valyala/fasthttp"
)

type HelloGoHandler struct {
   
}

func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
   
	fmt.Fprintln(ctx, "Hello, Go!")
}

func main() {
   
	go func() {
   
		http.ListenAndServe(":6060", 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值