Java NIO
java Nio
Selector 选择器
Buffer 缓冲器
Channel 通道
Selector是NIO的核心,是channel的管理者,通过执行select()阻塞方式,监听是否有channel准备好,一旦有数据可读,此方法的返回值是SelectionKey的数量。服务端通常会死循环执行select()方法,直到有channel准备就绪,然后开始工作,每个channel都会和Selector绑定一个事件,然后生成一个SelectionKey的对象。
channel和Selector绑定时,channel必须是非阻塞模式,而FileChannel不能切换到非阻塞模式,因为它不能套接字通道,所以FileChannel不能和Selector绑定事件。
在NIO中一共有四种事件:
1、SelectorKey.OP_CONNECT:连接事件
2、SelectorKey.OP_ACCEPT:接收事件
3、SelectorKey.OP_READ:读事件
4、SelectorKey.OP_WRITE:写事件
channel连接tcp端口和selector选择器,每次连接channel会新建一个吗,然后等准备好了就发送SelectionKey事件吗,有事件后channel读写到buffer吗?是这个顺序吗?
SelectionKey是Channel和Selector交互的核心组件,channel通过register绑定再selector上,并且注册为connect事件。Selector返回一个SelectionKey来检测channel事件,通过轮询判断事件类型,然后做相应操作,通过SelectionKey可以反过来拿到Channel和Selector。
tomcat NIO
connector
tomcat中Http11NioProtocol包含NioEndpoint实例,请求工作委托给NioEndpoint,tomcat在NioProtocol解析http请求时设计了三种线程,分别为Acceptor,Poller,Worker。
Acceptor run方法中包含执行过程。ServerSocketChannel执行阻塞接收操作,接收完成后setSocketOptions,设置为非阻塞,调用Poller的register方法,完成channel的注册。该方法的主要功能是利用传入的SocketChannel参数生成SecureNioChannel或者NioChannel,然后注册到Poller线程的selector中,注册中事件改为SelectionKey.OP_READ。
Poller线程,相当于Selector
Worker线程就是SocketProcessor用来处理实际业务请求,实现Runnable接口,通过线程池执行任务。
Container:
Container容器是所用servlet容器的父接口,也就是说作为一个servlet容器,首先必须要实现Container接口,每个tomcat服务器只能有唯一的根Container,Connector组件通过setContainer方法将Container容器和Connector关联起来。共有四种类型Container容器,分别对应不同概念的层次,每一层之间是父子的关系。
1、Engine:整个Catalina servlet引擎,标准实现为StandardEngine。
2、Host:表示包含一个或多个Context容器的虚拟主机,标准实现为StandardHost。
3、Context:表示一个web应用程序,一个Context可以有多个Wrapper,标准实现为StandardContext。
4、Wrapper:包装一个独立的Servlet容器,标准实现为StandardWrapper。