golang网络框架netpoll(Multi-Reactor模型)核心源码分析
Posted 半路出家的后台技术人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang网络框架netpoll(Multi-Reactor模型)核心源码分析相关的知识,希望对你有一定的参考价值。
现如今提起网络大家的第一反应就是epoll,而实际工程开发中绝大部分的情况都会优先考虑采用已有的一些开源网络框架来做功能的开发。网络框架不同的语言有不同的实现,例如java中大名鼎鼎的netty,再比如c++中的libevent、boost::asio、muduo等,golang中目前在开源社区比较有影响力的网络框架有gnet、evio、netpoll(字节开源)这几个。在之前研究完gnet后差不多一年多的时间了,近期机缘巧合又抽空研究了下netpoll的源码实现。在此总结一篇源码分析的文章,方便日后回顾。
netpoll是字节不久前开源的一款golang编写的高性能网络框架(基于Multi-Reactor模型),旨在用于处理rpc场景,详细的介绍可参见下图介绍。
下面将为大家详细分析其内部的源码实现逻辑。其他系列文章参见如下:
1. 网络IO演变过程
2. gnet网络框架源码剖析
我们在开始netpoll框架的源码分析前,方便大家阅读源码有一个更好的体验,先简单的回顾下网络编程中的Reacor模型吧。目前很多主流的网络框架都会采用经典的Reactor模型来进行框架内部的实现。而Reactor模型中用的最频繁的就属Multi-Reactor了,最基本的Multi-Reactor模型框架如下图所示。
Multi-Reactor模型中根据角色的不同,可以将Reactor分类两类:mainRactor、subReactor。一般mainReactor是一个,而subReactor会有多个。
Multi-Reactor模型的原理如下:
1. mainReactor主要负责接收客户端的连接请求,建立新连接,接收完连接后mainReactor就会按照一定的负载均衡策略分发给其中一个subReactor进行管理。
2. subReactor会将新的客户端连接进行管理,负责后续该客户端的请求处理。
3. 通常Reactor线程主要负责IO的操作(数据读写)、而业务逻辑的处理会由专门的工作线程来执行。
备注:此处所指的Reactor,以epoll为例可以简单理解成一个Reactor对应于一个epoll对象,由一个线程进行处理,Reactor线程又称为IO线程。
简单回顾完Multi-Reactor模型的原理后,下面我们进入正式的主题:netpoll网络框架的源码分析。
2. netpoll整体框架2.1 netpoll client和server端的交互过程netpoll中对client和server都进行了封装,通过netpoll可以快速的创建一个server端程序。同时可以采用其提供的client方法可以和server进行交互。下面是client和server的一个完整的交互过程。
在netpoll中针对server端,它提供了以下几个方法和回调接口它们的功能分别如下:
Serve():启动服务端,监听等待客户端的请求 OnPrepare():主要做一些初始化、准备的工作,创建连接前回调
OnConnect():在连接创建后回调
OnRequest():业务逻辑方法回调,实现业务逻辑异步处理
下面这张图侧重于介绍netpoll中server端的核心逻辑,其实现原理和前面介绍的Multi-Reactor模型基本一致,其中Listener、loadbalance、pollmanager、EventLoop等都是netpoll中核心的概念,下面我们再对其做一一介绍。
Listener:主要用来初始化Listener,内部调用标准库的net.Listen(),然后再封装了一层。具体的实现则是调用socket()、bind()、listen()等系统调用。
EventLoop:框架对外提供的接口,对外暴露Serve()方法来创建server端程序。
Poll: 是抽象出的一套接口,屏蔽底层不同操作系统平台接口的差异,linux下采用epoll来实现、bsd平台下则采用kqueue来实现。
pollmanager:Poll的管理器,可以理解成一个Poll池,也就是一组epoll或者kqueue集合。
loadbalance:负责均衡封装,主要用来从pollmanager按照一定的策略(随机、轮询、最小连接等)选择出来一个Poll实例,一般在客户端初始化完成后,server会调用该接口拿到一个Poll实例,并将新建立的客户端加入到Poll管理。
下面是netpoll的一个简单使用示例,从中我们可以看到它对外暴露的api的使用姿势。
listeneraddress eventLoopconnection Connection timetime l connectionl dataerr connection err err
fmt eventLoopEventLoop OnRequest connection Connectionops opts onRequestonRequest do ops do optsopts stop eventLoop sync svr opts stop nplnerr err err
evl evlevlevl evl evl err evl runtime err
opts onQuit ln ln opts opts onQuitonQuit server operator FDOperator
ln Listener
opts onQuit connections sync sFDOperator FD s OnReads OnHup s spollmanager err s err s err
connerr s err strings s s err
logerr err
conn connection connections fd conn connection s sconnection connection spollmanager err s connectionsopts c