mina服务端通信概括起来有如下几个过程,1、创建服务端接收器IoAcceptor。2、绑定相应的接口并进行监听。3、接收到请求后读取socket并调用过滤器解析socket。5、处理请求并将处理结果使用异步的方式写回客户端。
那么我们先来看看mina创建接收器的过程。在mina框架中,接收器用IoAcceptor接口表示,其TCP协议实现类为NioSocketAcceptor。NioSocketAcceptor类继承AbstractPollingIoAcceptor类,因此在实例化NioSocketAcceptor之前先调用AbstractPollingIoAcceptor的构造函数并进行实例化。实例化AbstractPollingIoAcceptor的之前会创建一个IoProcessor类型的线程池,默认大小为CPU的核数+1。IoProcessor线程的作用是完成数据的读写操作。至于IoProcessor线程数量为什么只比CPU核数大一,是因为I/O读写操作是比较耗CPU的操作,而每核CPU同时只能运行一个线程,线程数量过多的话会导致频繁的线程切换,反而降低了处理效率,因此IoProcessor的数量不是越多越好。
public NioProcessor(Executor executor) {
super(executor);
try {
// Open a new selector
selector = Selector.open();
} catch (IOException e) {
throw new RuntimeIoException("Failed to open a selector.", e);
}
}
实例化IoProcessor线程的时候会在它们的构造方法中为每一个实例单独创建Selector选择器。
在AbstractPollingIoAcceptor的构造方法中首先继续往上实例化父类,在实例化AbstractIoService类的时候会创建一个IoAcceptor线程池,IoAcceptor线程的作用是接收客户端的连接请求。然后调用NioSocketAcceptor的init创建IoAcceptor线程相关的Selector选择器。
protected void init(SelectorProvider selectorProvider) throws Exception {
this.selectorProvider = selectorProvider;
if (selectorProvider == null) {
selector = Selector.open();
} else {
selector = selectorProvider.openSelector();
}
}
前面我们有说到每个IoProcessor线程都有单独的Selector选择器,这里又为IoAcceptor线程创建Selector选择器,这样做的目的就是将接受连接请求与I/O读写操作这两部分交给不同的线程分开处理。I/O读写操作一般比较耗时,如果将连接请求的操作与读写操作在同一个线程中进行处理,那么服务器端接收到请求以后只能等待读写操作完成才能接收下一个请求,这样无疑会影响服务端的处理效率。
未完待续。。。。。。