深入理解深入理解Netty线程模型线程模型
当我们谈论Netty的线程模型时,首先会想到的是经典的Reactor IO多路复用线程模型。从这篇文章中,大家可以学习到如下
知识:
什么是I/O多路复用
Reactor三种线程模型
Netty线程模型
NioEventLoop源码分析
JDK epoll bug
什么是I/O多路复用
学习I/O多路复用之前,我们先来了解如下几个概念:
阻塞I/O:客户端从socket中读取数据或写入数据时,如果读取时流中没有数据,写入时缓冲区已满,就需要block,知道流中
有数据或者缓冲区的数据被排空。
非阻塞I/O:客户端从流中读取数据,如果流中没有数据,则立即返回,不发生block。
同步I/O:同步I/O将导致请求的I/O操作一直被block,直到I/O完成。
异步I/O:异步I/O不会导致block,发出I/O请求后立即返回,直到完成I/O操作后再异步通知调用进程。
I/O多路复用可以监视多个FD(文件描述符),一旦某个FD准备就绪,就会通知相应进程处理。多路复用也是阻塞的,阻塞的
方法是select/poll/epoll,可以在单个进程中同时处理多个I/O请求,原理是采用轮询的方式便利所有的I/O操作,当某些I/O有数
据时,就通知用户进程处理。
select:系统提供select函数来实现多路复用输入/输出模型,select系统调用是用来让我们的程序监视多个文件句柄的状态变
化。程序会阻塞在select函数上,直到被监视的文件句柄中有一个或多个发生了状态变化。
poll:poll函数与select函数的最大不同之处在于:select函数有最大文件描述符的限制,一般1024个,而poll函数对文件描述
符的数量没有限制。
epoll:
监视的描述符数量不受限制,所支持的FD上限是Linux系统最大可以打开文件的数目;
I/O效率不会随着监视fd的数量增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的,
只有就绪的fd才会执行回调函数。
Reactor三种线程模型
1. Reactor单线程模型
是指所有的I/O操作都在同一个NIO线程上完成,职责如下
作为NIO服务端,接收客户端TCP连接
作为NIO客户端,向服务端发起TCP连接
读取对端请求或者应答消息
向对端发送请求或者应答消息