超高连接数场景下,越来越多的第三方库开始使用裸的epoll来实现,相继出现了Evio,Gnet和本系列主要讨论的Netpoll。
随着Go语言的运用越来越广,Go原生的net组件在一些场景下逐渐开始乏力。比如一个需要超高连接数服务的场景下,我们如果使用Go自动的net库,每一个新Client Go net库会分配一个goroutine。我们知道goroutine的默认栈是2k,在超大连接数等于有超高的goroutine,会产生很大的内存占用。而且超多的goroutine会让go调度器调度难度增大。
为了解决这个问题,Go社区里开始出现了抛开go原生net,使用裸epoll的解决方案。比较受欢迎的有evio,gnet,以及本系列专栏想讨论的字节跳动开源的netpoll。
在Go中如何使用裸的epoll?§
1m-go-websockets 这个项目有比较简洁易懂的代码实现。也可以参考笔者的练手项目poller。
Reactor模型§
epoll最终反馈到用户态的是一个事件数组,我们根据事件数组处理各个事件,这种基于事件的处理模型我们称之为Reactor
模型。
Netpoll§
Netpoll是字节开源的基于Reactor模型的纯golang实现的网络库。字节基于Netpoll开发出了KitexRPC框架和Hertzhttp框架,从官方的基准测试结果来看,其性能还是比较出众的。
Netpoll 核心组件§
- LinkBuffer提供可以流式读写的 nocopy API
- gopool 提供高性能的
goroutine
池 - mcache 提供高效的内存复用
本系列会从Netpoll源码角度分析,Netpoll的实现细节。
评论