Skip to content
清晨的一缕阳光
返回

Hertz 高性能框架

Hertz 高性能框架

Hertz 是字节开源的高性能 HTTP 框架,采用自研网络层和 Reactor 模型,性能卓越。

一、架构概览

1.1 核心组件

Hertz 架构
├── Network Layer(网络层)
│   ├── netpoll(自研网络库)
│   └── I/O Multiplexing(IO 多路复用)
├── Protocol Layer(协议层)
│   ├── HTTP/1.1
│   ├── HTTP/2
│   └── WebSocket
├── Router(路由)
│   └── Radix Tree(基数树)
└── Middleware(中间件)
    └── Chain(责任链)

1.2 快速入门

package main

import (
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
)

func main() {
    h := server.Default()
    
    h.GET("/hello", func(c context.Context, ctx *app.RequestContext) {
        ctx.JSON(200, map[string]string{
            "message": "Hello Hertz",
        })
    })
    
    h.Spin()
}

二、netpoll 网络层

2.1 Reactor 模型

Hertz Reactor 模型
├── Main Reactor(主反应器)
│   └── 接受连接
├── Sub Reactors(子反应器)
│   ├── Reactor 1
│   ├── Reactor 2
│   └── Reactor N
└── Worker Pool(工作池)
    └── 处理业务逻辑

2.2 事件循环

// 简化的事件循环
type EventLoop struct {
    poller *Poller
    conn   *Conn
}

func (el *EventLoop) Run() {
    for {
        events, err := el.poller.Wait()
        if err != nil {
            continue
        }
        
        for _, event := range events {
            switch event.Type {
            case ReadEvent:
                el.handleRead(event)
            case WriteEvent:
                el.handleWrite(event)
            }
        }
    }
}

2.3 零拷贝

// 使用 nocopy 优化
type Request struct {
    nocopy nocopy.NoCopy  // 禁止复制
    Header RequestHeader
    Body   []byte
}

// 内存池
var requestPool = sync.Pool{
    New: func() any {
        return &Request{}
    },
}

func getRequest() *Request {
    return requestPool.Get().(*Request)
}

func putRequest(req *Request) {
    req.Reset()
    requestPool.Put(req)
}

三、路由系统

3.1 基数树路由

// 路由注册
h.GET("/users/:id", handler)
h.GET("/users/:id/posts/:postId", handler)

// 路由匹配过程
// /users/123/posts/456
// ↓
// 匹配 /users/:id/posts/:postId
// ↓
// 提取参数 id=123, postId=456

3.2 路由组

// 路由组
v1 := h.Group("/api/v1")
{
    v1.GET("/users", listUsers)
    v1.POST("/users", createUser)
}

// 带中间件的路由组
auth := h.Group("/admin", AuthMiddleware())
{
    auth.GET("/dashboard", dashboard)
}

四、中间件系统

4.1 中间件定义

// 中间件函数
type HandlerFunc func(c context.Context, ctx *app.RequestContext)

// 日志中间件
func Logger() app.HandlerFunc {
    return func(c context.Context, ctx *app.RequestContext) {
        start := time.Now()
        path := string(ctx.Request.URI().Path())
        
        ctx.Next(c)
        
        latency := time.Since(start)
        status := ctx.Response.StatusCode()
        
        hertzlog.Infof("[%d] %s %v", status, path, latency)
    }
}

4.2 中间件链

// 注册中间件
h.Use(Recovery(), Logger(), CORS())

// 执行顺序
// 1. Recovery (Before)
// 2. Logger (Before)
// 3. CORS (Before)
// 4. Handler
// 5. CORS (After)
// 6. Logger (After)
// 7. Recovery (After)

五、性能优化

5.1 内存池

// 字节切片池
var bytePool = sync.Pool{
    New: func() any {
        return make([]byte, 4096)
    },
}

func getBuffer() []byte {
    return bytePool.Get().([]byte)
}

func putBuffer(buf []byte) {
    if cap(buf) == 4096 {
        bytePool.Put(buf[:0])
    }
}

5.2 连接复用

// Keep-Alive 支持
h := server.Default(
    server.WithKeepAlive(true),
    server.WithIdleTimeout(60 * time.Second),
)

// 连接池
transport := &http.Transport{
    MaxIdleConns:        100,
    MaxIdleConnsPerHost: 10,
    IdleConnTimeout:     90 * time.Second,
}

5.3 性能对比

性能测试(Request/Second,越高越好)

Hertz:     150,000 req/s
Gin:       100,000 req/s
Echo:       95,000 req/s
net/http:   80,000 req/s

Hertz 性能优势:
1. 自研 netpoll 网络层
2. 零拷贝优化
3. 内存池复用
4. 智能预分配

六、最佳实践

6.1 项目结构

project/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   ├── handler/
│   ├── middleware/
│   ├── model/
│   └── service/
├── pkg/
│   └── utils/
└── configs/

6.2 错误处理

// 统一错误处理
func handleError(c context.Context, ctx *app.RequestContext, err error) {
    var httpErr *HTTPError
    if errors.As(err, &httpErr) {
        ctx.JSON(httpErr.Status, httpErr)
        return
    }
    
    ctx.JSON(500, map[string]string{
        "error": "Internal error",
    })
}

6.3 优雅关闭

h := server.Default()

// 注册优雅关闭
h.OnShutdown = append(h.OnShutdown, func(ctx context.Context, server *server.Hertz) error {
    log.Println("Shutting down...")
    return nil
})

// 启动
h.Spin()

七、总结

Hertz 核心要点:

组件实现特点
网络层netpoll自研、Reactor 模型
路由基数树O(log n) 匹配
中间件责任链灵活组合
性能内存池 + 零拷贝15 万 + QPS

Hertz 通过自研网络层和零拷贝优化,实现了卓越的性能,适合高并发场景。


分享这篇文章到:

上一篇文章
Spring Boot Testcontainers 测试实战
下一篇文章
Spring Boot 启动流程与生命周期