Hertz 网络库指南
底层网络库
Hertz 默认集成了 Netpoll 和 Golang 原生网络库两个网络库,用户可以根据自己的场景选择合适的网络库以达到最佳性能。
Netpoll简介
Netpoll 是由 字节跳动 开发的高性能 NIO(Non-blocking I/O)网络库,专注于 RPC 场景。
RPC 通常有较重的处理逻辑,因此无法串行处理 I/O。
而 Go 的标准库 net 设计了 BIO(Blocking I/O) 模式的 API,使得 RPC 框架设计上只能为每个连接都分配一个 goroutine。
这在高并发下,会产生大量的 goroutine,大幅增加调度开销。
此外,net.Conn 没有提供检查连接活性的 API,因此 RPC 框架很难设计出高效的连接池,池中的失效连接无法及时清理。
另一方面,开源社区目前缺少专注于 RPC 方案的 Go 网络库。
类似的项目如:evio, gnet 等,均面向 Redis, HAProxy 这样的场景。
因此 Netpoll 应运而生,它借鉴了 evio 和 netty 的优秀设计,具有出色的 性能,更适用于微服务架构。
同时,Netpoll 还提供了一些 特性,推荐在 RPC 设计中替代 net 。
基于 Netpoll 开发的 RPC 框架 Kitex 和 HTTP 框架 Hertz,其性能均业界领先。
范例 展示了如何使用 Netpoll 构建 RPC Client 和 Server。
Netpoll特性
- 已经支持
- LinkBuffer 提供可以流式读写的 nocopy API
- gopool 提供高性能的 goroutine 池
- mcache 提供高效的内存复用
IsActive
支持检查连接是否存活Dialer
支持构建 clientEventLoop
支持构建 server- 支持 TCP,Unix Domain Socket
- 支持 Linux,macOS(操作系统)
- 即将开源
- Shared Memory IPC
- 支持 TLS
- 支持 UDP
- 不被支持
- Windows(操作系统)
Netpoll性能
性能测试应满足工业级使用要求,在 RPC 场景下,并发请求、等待超时是必要的支持项。
相关方法
// 获取当前网络库
func (engine *Engine) GetTransporterName() (tName string)
// 设置当前网络库
func SetTransporter(transporter func (options *config.Options) network.Transporter)
GetTransporterName
获取当前使用的网络库名称,现在有原生的 go net
和 netpoll
两种。
linux 默认使用 netpoll
, windows 只能使用 go net
。
函数签名:
func (engine *Engine) GetTransporterName() (tName string)
示例代码:
h := server.New()
tName := h.GetTransporterName()
SetTransporter
SetTransporter
用于设置网络库。
注意:
SetTransporter
只设置 Engine 的全局默认值,所以在初始化 Engine 时使用WithTransporter
来设置网络库会覆盖掉SetTransporter
的设置。
函数签名:
func SetTransporter(transporter func (options *config.Options) network.Transporter)
示例代码:
import (
"github.com/cloudwego/hertz/pkg/network/netpoll"
"github.com/cloudwego/hertz/pkg/network/standard"
)
route.SetTransporter(standard.NewTransporter)
// 在windows中无法使用
server.WithTransport(netpoll.NewTransporter)
例子
package main
import (
"fmt"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/network/netpoll"
)
func main() {
// 设置 netpoll网络库
h := server.Default(server.WithTransport(netpoll.NewTransporter))
// 获取当前使用的网络库
fmt.Println(h.GetTransporterName())
}
使用方式
对于 Server 来说,默认使用 netpoll,可以通过配置项进行更改:
注意:netpoll 目前不支持 Windows,Windows 会通过条件编译将网络库自动切换为 go net。
server.New(server.WithTransport(standard.NewTransporter))
server.New(server.WithTransport(netpoll.NewTransporter))
对于 Client 来说,可以通过配置项进行更改:
client.NewClient(client.WithDialer(standard.NewDialer()))
client.NewClient(client.WithDialer(netpoll.NewDialer()))
网络库选择
-
如果有启动 TLS Server 的需求,请使用
go net
网络库。netpoll
正在实现对 TLS 的支持。 -
由于网络库触发模式的不同:
go net
为 ET 模型,netpoll
为 LT 模型,使得两个网络库的适用场景有一些不同。在 ET 模型下,由框架处理 Read / Write 事件;在 LT 模型下,由网络库处理 Read / Write 事件。
使得在小包场景下,由于更优的调度策略使得 LT 性能更好;在大包场景下,由于读 / 写不受框架层控制,使得大量数据被读入内存而不能及时处理,可能会造成内存压力。
- 在较大 request size 下(request size > 1M),推荐使用 go net 网络库加流式。
- 在其他场景下,推荐使用 netpoll 网络库,会获得极致的性能。
本文来自博客园,作者:厚礼蝎,转载请注明原文链接:https://www.cnblogs.com/guangdelw/p/18735533
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2023-02-25 接口断言为切片的问题
2023-02-25 SaaS、PaaS、IaaS的区别
2023-02-25 Go语言中密码加密校验
2023-02-25 通过阿里云拉取Google云上的镜像
2023-02-25 Containerd 客户端工具
2023-02-25 docker基础与概念
2023-02-25 通过k8s完成线上业务的金丝雀发布