NIO的通信框架,目前最火的当属Mina,Netty,Grizzly。
Mina(Multipurpose Infrastructure for Network Applications) 是
Apache组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。
Netty是一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。
Grizzly是一种应用程序框架,专门解决编写成千上万用户访问服务器时候产生的各种问题。
MINA与
NETTY基本上算出于同一主导作者(Trustin Lee韩国80后),所以代码结构与开发目标大体一致,NETTY更像在mina基础上的重构以及优化。如果说Netty比Mina性能好很多,这种机会不是很大。目前NETTY的更新更加频繁,文档非常全。想选择的MINA的人,基本有理由选择NETTY。
而
Grizzly是一种应用程序框架,更适合用于基于HTTP的应用。而且Grizzly的结构相对前两者比较绕,没有他们清晰。这两方面也许是Grizzly没有得以流行的原因。目前只在SUN/ORACLE的项目采用Grizzly。但作为JAVA的老东家的作品,必须有基可取之处。
先看看
MINA结构图:
简单地来讲,就分为三层:
1. I/O Service。负责处理I/O,直接子接口: IoAcceptor,IoConnector
2. I/O Filter Chain。负责编码处理,字节到数据结构或数据结构到字节的转换等,即非业务逻辑的操作。
3. I/O Handle。负责处理业务逻辑。
IoAcceptor服务端,IoConnector相当于客户端。
接受连接之后
,创建一个NioSession,相当于一个连接实现。然后交由处理线程(Processor)处理。Processor该连接上的事件,交给FilterChain处理,FilterChain里含有很多Filter,他们按顺序处理请求,接收请求与响应回复都需要经过所有的filter,就像Servlet里的Filter.最后交由IOHandler。结构很清晰。
Netty基本上也是这一结构,接受连接之后
,创建一个NioSocketChannel, 然后交由处理线程NioWorker去处理。对于FilterChain,Netty对应为ChannelPipeline.
在
Netty里没有filter与handler之分.统统叫handler,同时netty把Handler分两种:Upstream Handler, Downstream Handler,接收请求只走Upstream Handler,回复响应只走Downstream Handler,当然一个Handler可以同是Upstream Handler和 Downstream Handler。
以下是
netty的ChannelPipeline结构:
默认情况下,
mina启动(Runtime.getRuntime().availableProcessors() + 1)个Processor线程.Netty启动Runtime.getRuntime().availableProcessors() * 2个NioWorker线程。
有朋友默认情况下性能测试,
Netty优于Mina,检查一下是不是Netty在线程数量上优于Mina。
某些情况下
,业务逻辑会成为Processor线程的瓶颈,比如DB操作。该处理线程所关联的其他连接都会因为某一个连接的DB操作而无法响应。Mina与Netty分别提供了ExecutorFilter
/
ExecutionHandler
把业务逻辑处理从处理线程中剥离出来。
再说一下
Grizzly
,如果以
Selector
个数来划分处理线程的话,
Grizzly
默认情况下只有两个处理线程
(SelectorRunner)
,甚至说只有一个。
Grizzly
没有所谓的
Boss(netty)
,
Acceptor(mina)线程,也就是说
Grizzly
没有单独的线程来处理连接
(connect)
请求。
SelectionKey.OP_ACCEPT
也是在这两个
SelectorRunner
中处理。如果仅此两个处理线程,当前是不行的。所以对应于Mina与
Netty的 ExecutorFilter
/
ExecutionHandler
,
Grizzly
提供好几个
IO
策略用于
把业务逻辑处理从处理线程中剥离出来
:
LeaderFollowerNIOStrategy
,
SameThreadIOStrategy
,
WorkerThreadIOStrategy
,
SimpleDynamicNIOStrategy
。
默认为
WorkerThreadIOStrategy
这样并发能力马上就上来了。
另外一点不同,Mina与netty对于数据流到业务对象的解析与反解析放在处理线程中,而Grizzly把这一工作交给了业务逻辑线程,而处理线程只做事件的分发任务。
这倒符合他只有默认两个处理线程的初衷。从软件工程角度上看,前两者在功能分离上更好一些。(未完)
本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/841342