Mina源码研究心得
1.整体结构
Mina官方教程中的总体结构图:
IoService是用于执行具体的IO操作(发送&接收数据),如NioTcpServer是IoService的实现类之一,其作用是使用NIO提供的Selector实现TCP的服务端。
IoFilterChain实际上是一个Filter数组,通过IoService.setFilters方法设置所有的Filter。
IoHandler接口需要在应用层实现,Mina在接收到数据后,将读取的数据交给IoHandler处理,同时Mina会将IoHandler中需要写回远程机器的数据写入通道。
2.主要类与接口
Mina的继承结构略有点复杂,但继承结构中的每一层的作用则很清晰,IoService用于对IoSession,Filter和IoHandler的管理,AbstractIoServer用于处理绑定的端口与ip等。
3.Mina线程模型
线程模型我认为是Mina中的精华部分了,以NioTcpServer为例,它可以选择使用主-从Reactor模式。
JDK1.4中引入了NIO,主要包括Channel和Buffer以及Selector,Selector提供了多路复用的功能。有了Selector后可使用多路复用高效处理IO。
Mina线程模型图(网上copy的主从Reactor模式):
在Mina中,一个Acceptor或者一个Main Reactor Thread是由一个SelectorLoop对象表示,SelectorLoop中包含SelectorWorker(Thread的子类)和Selector,而Accept Pool则是SelectorLoop数组。
Acceptor是一个用于接收Client连接的线程,Acceptor只用于接收客户端连接,一旦有Client连接请求,Acceptor建立连接后将打开的SocketChannel注册到一个Main Reactor Worker中。
Main Reactor Worker线程用于处理Read/Write操作,Mina框架中,NioSelectorLoop读取到Client的数据后,将ByteBuffer注册到IO Pool交给Sub Reactor Thread处理(调用IoHandler)。
写数据时,应用只需要在IoHandler中调用Response.write方法,但它不是实际的写操作,它会把需要写的数据保存在IoSession的Queue里,当Main Reactor Thread中的selector选择到可写事件时,会调用IoSession的ready方法将数据写到SocketChannel中。
4.Mina中的缺点
目前发现Mina的代码中的一个问题会影响到Mina的性能,Mina中,一个NioSelectorLoop中包含一个默认大小为64k的ByteBuffer,是直接缓冲区(ByteBuffer.allocateDirect(64 * 1024)),用于读取数据,但一个NioSelectorLoop不只是承担一个Client的数据读取任务,它读取一个Client的数据后,需要将此ByteBuffer中的数据复制到另一个ByteBuffer中,然后将新的ByteBuffer提交交给IO Pool。保证了读取一个Client的数据后可以马上读取下一个Client的数据。每次复制数据时都重新allocate一个新的ByteBuffer。如果能实现一个持有ByteBuffer的对象池,每次读取数据时从池里拿对象,可以避免ByteBuffer的频繁创建与销毁(ByteBuffer的创建与销毁代价较大),也可以避免复制ByteBuffer中的数据。
5.Filter的作用
Filter可用于处理应用层协议,如HTTP,FTP等,如利用Mina实现Http Server:
这是Mina中的Example,DummyHttpServer用于处理数据。