一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
背景
-
Reactor模式,即反应器模式。Netty整体架构是Reactor模式的完整体现。
-
Reactor模式基本都应用在网络编程。而Netty其实是Java网络编程的杰出开源框架。Reactor是异步,事件驱动,多线程的。Netty是事件为中心,事件驱动的,Netty是理论Reactor模式的实践。
-
传统网络编程
传统基于阻塞io编写的ServerSocket,是一个用户一个线程新分配一个空闲端口。而我们的端口号有两类,比如第一个8899就是客户端连接的端口号,而另一个端口号是操作系统寻找空闲的端口,这个端口才是与客户端真正进行数据双向传递。
-
NIO是异步编程模型,它是一个线程应对所有客户端请求的。跟Node编程模型是一样的。所有异步编程都离不开Event。比如Ajax请求,连接成功是一个事件,当连接成功后,其实我们可以执行某些具体的逻辑。当服务器响应成功后,这是一个事件,然后我们执行Ajax的回调函数。如果服务器响应失败了,这其实也是一个事件,然后我们执行错误的方法即可。这就是异步基于事件的工作模式。
-
理解Reactor模式的发展过程。
a) 传统I/O的每一个客户端都需要建立一个线程,在同一个handler中处理整个流程,read,decode, compute, encode, send。
b) 单线程的Reactor,可以使用java.nio可以实现,一个Reactor线程进行事件分发,事件进行分类处理,每一类都是独立的线程,相互之间互不影响。
c) 单线程的Reactor。线程池实现Handler的方式,则可以对线程池进行调节。worker threads 进行decode, compute, encode任务。
d) 多个Reactor(Reactor的最佳实践)。每个Reactor都有Selector, Thread, Dispatch。
关系分析
- Netty是理论Reactor模式的实践。
-
mainReactor相当于Netty中的bossGroup(EventLoopGroup),它有独立的Initation Dispatcher, Handle, Event Handler, Concrete EventHandler(开发者定义的事件处理器),事件分离器(select()这是一个阻塞方法)。
-
subReactor相当于Netty中的workerGroup(EventLoopGroup),它有独立的Initation Dispatcher, Handle, Event Handler, Concrete EventHandler(开发者定义的事件处理器),事件分离器(select()这是一个阻塞方法)。
-
mainReactor与subReactor中的“状态转移”是采用acceptor进行的。在Netty中,其实是bossGroup在启动的时候,通过方法channelRead把workerGroup添加到pipline中进行关联上的,目的就是当连接来的时候,boosGroup进行处理,并把连接状态给到workerGroup,这样后续客户端发来的数据传输过程,就是subReactor直接进行处理的,也就是workerGroup直接监听OP_READ事件。
源代码过程就是,ServerbootStrap在绑定端口的时候,把workerGroup当成handler添加到bossGroup中。图中p是ChannelPipline的对象。
- 实践中,一般来说,bossGroup给一个线程即可;而workerGroup采用线程池方式;业务逻辑也是采用线程池方式实现。
小结
-
通过理解Reactor模式的演进过程,理解它的最佳实践。
-
通过Reactor模式的组件概念映射到Netty中的概念,发现他们是一一对应的,所以Netty其实就是Reactor模式的实践。
-
理解三个线程组。bossGroup,workerGroup,完成业务逻辑执行的线程池。