golang高性能HTTP实现插件库fasthttp的使用
Golang 高性能 HTTP 实现插件库 fasthttp 的使用
简介
fasthttp 是 Go 语言中一个高性能的 HTTP 实现库,专为处理高并发场景设计。相比标准库 net/http,fasthttp 在某些场景下性能可提升 10 倍。
适用场景
fasthttp 专为高性能边缘案例设计。除非您的服务器/客户端需要处理每秒数千个中小型请求并且需要一致的毫秒级响应时间,否则 fasthttp 可能不适合您。对于大多数情况,net/http
更好,因为它更易于使用且能处理更多情况。
性能对比
HTTP 服务器性能对比
fasthttp 服务器比 net/http 快 10 倍:
GOMAXPROCS=1
net/http 服务器:
BenchmarkNetHTTPServerGet1ReqPerConn 1000000 12052 ns/op 2297 B/op 29 allocs/op
BenchmarkNetHTTPServerGet2ReqPerConn 1000000 12278 ns/op 2327 B/op 24 allocs/op
fasthttp 服务器:
BenchmarkServerGet1ReqPerConn 10000000 1559 ns/op 0 B/op 0 allocs/op
BenchmarkServerGet2ReqPerConn 10000000 1248 ns/op 0 B/op 0 allocs/op
HTTP 客户端性能对比
fasthttp 客户端比 net/http 快 10 倍:
GOMAXPROCS=1
net/http 客户端:
BenchmarkNetHTTPClientDoFastServer 1000000 12567 ns/op 2616 B/op 35 allocs/op
BenchmarkNetHTTPClientGetEndToEnd1TCP 200000 67030 ns/op 5028 B/op 56 allocs/op
fasthttp 客户端:
BenchmarkClientDoFastServer 20000000 865 ns/op 0 B/op 0 allocs/op
BenchmarkClientGetEndToEnd1TCP 1000000 18711 ns/op 0 B/op 0 allocs/op
安装
go get -u github.com/valyala/fasthttp
基本使用示例
简单 HTTP 服务器
package main
import (
"fmt"
"github.com/valyala/fasthttp"
)
func main() {
// 定义请求处理函数
requestHandler := func(ctx *fasthttp.RequestCtx) {
switch string(ctx.Path()) {
case "/hello":
ctx.SetContentType("text/plain")
ctx.SetStatusCode(fasthttp.StatusOK)
ctx.WriteString("Hello, World!")
default:
ctx.Error("Not Found", fasthttp.StatusNotFound)
}
}
// 启动服务器
if err := fasthttp.ListenAndServe(":8080", requestHandler); err != nil {
fmt.Printf("Error in ListenAndServe: %s", err)
}
}
绑定结构体方法作为处理器
package main
import (
"fmt"
"github.com/valyala/fasthttp"
)
type MyHandler struct {
greeting string
}
// 绑定到结构体的请求处理方法
func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "%s, Requested path is %q", h.greeting, ctx.Path())
}
func main() {
myHandler := &MyHandler{
greeting: "Welcome",
}
fasthttp.ListenAndServe(":8080", myHandler.HandleFastHTTP)
}
HTTP 客户端示例
package main
import (
"fmt"
"github.com/valyala/fasthttp"
)
func main() {
// 创建客户端
client := &fasthttp.Client{}
// 创建请求和响应对象
req := fasthttp.AcquireRequest()
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseRequest(req)
defer fasthttp.ReleaseResponse(resp)
// 设置请求
req.SetRequestURI("http://example.com")
req.Header.SetMethod("GET")
// 发送请求
if err := client.Do(req, resp); err != nil {
fmt.Printf("Error: %s\n", err)
return
}
// 输出响应
fmt.Printf("Status: %d\n", resp.StatusCode())
fmt.Printf("Body: %s\n", resp.Body())
}
从 net/http 切换到 fasthttp
fasthttp 的 API 与 net/http 不兼容,主要区别包括:
- fasthttp 使用
RequestHandler
函数而不是实现Handler
接口的对象 RequestHandler
只接受一个参数 -RequestCtx
- fasthttp 允许以任意顺序设置响应头和写入响应体
转换示例
net/http 代码:
m := &http.ServeMux{}
m.HandleFunc("/foo", fooHandlerFunc)
m.HandleFunc("/bar", barHandlerFunc)
m.Handle("/baz", bazHandler)
http.ListenAndServe(":80", m)
对应的 fasthttp 代码:
m := func(ctx *fasthttp.RequestCtx) {
switch string(ctx.Path()) {
case "/foo":
fooHandlerFunc(ctx)
case "/bar":
barHandlerFunc(ctx)
case "/baz":
bazHandler.HandlerFunc(ctx)
default:
ctx.Error("not found", fasthttp.StatusNotFound)
}
}
fasthttp.ListenAndServe(":80", m)
性能优化技巧
- 使用
reuseport
监听器 - 每个 CPU 核心运行一个单独的服务器实例,设置 GOMAXPROCS=1
- 使用
taskset
将每个服务器实例固定到单独的 CPU 核心 - 确保多队列网卡的中断在 CPU 核心之间均匀分布
- 使用最新版本的 Go
最佳实践
- 尽可能重用对象和
[]byte
缓冲区 sync.Pool
是你的好朋友- 在生产环境中分析程序性能
- 为热点路径编写测试和基准测试
- 避免在
[]byte
和string
之间转换 - 定期使用 race detector 检查代码
- 使用
quicktemplate
而不是html/template
零分配转换技巧
fasthttp 提供了一些零分配转换函数:
// UnsafeString 返回字符串指针而不分配内存
func UnsafeString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// UnsafeBytes 返回字节指针而不分配内存
func UnsafeBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
警告:这些转换破坏了 Go 的类型安全性。仅当您确定转换后的值不会被修改时才使用它们。
相关项目
- fasthttp-routing - 快速强大的路由包
- router - 高性能请求路由器
- Fiber - 受 Express 启发的 Web 框架
- Gearbox - 高性能 Web 框架
常见问题
为什么创建 fasthttp 而不是优化 net/http?
因为 net/http API 限制了许多优化机会。例如:
- net/http Request 对象生命周期不受请求处理程序执行时间限制
- net/http 头信息存储在
map[string][]string
中,需要额外转换
fasthttp 支持 HTTP/2.0 和 WebSockets 吗?
HTTP/2.0 支持正在进行中,WebSockets 已经实现。
更多关于golang高性能HTTP实现插件库fasthttp的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复