Apache Mina 是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过 Javanio 技术基于 TCP/IP 和 UDP/IP 协议提供了抽象的、事件驱动的、异步的 API 。
如下的特性:
1 、 基于 Java nio 的 TCP/IP 和 UDP/IP 实现
基于 RXTX 的串口通信( RS232 )
VM 通道通信
2 、通过 filter 接口实现扩展,类似于 Servlet filters
3 、 low-level (底层)和 high-level (高级封装)的 api :
low-level :使用 ByteBuffers
High-level :使用自定义的消息对象和解码器
4 、 Highly customizable (易用的)线程模式( MINA2.0 已经禁用线程模型了):
单线程
线程池
多个线程池
5 、基于 java5 SSLEngine 的 SSL 、 TLS 、 StartTLS 支持
6 、负载平衡
7 、使用 mock 进行单元测试
8 、 jmx 整合
9 、基于 StreamIoHandler 的流式 I/O 支持
10 、 IOC 容器的整合: Spring 、 PicoContainer
11 、平滑迁移到 Netty 平台
在 2.0.x 中对 Spring 等 IoC 的集成进行了简化,添加了基于 OGNL 的 JMX 远程管理支持,使用基于 Java Annotation 的全新 API 大大简化了状态机编程,新的基于 Apache APR 的基础 I/O 组件促进了进一步的效率提升(据官方评测, APR 的效率较之 Sun NIO 要高出约 10% )。
异步 I/O 模型大体上可以分为两种,反应式( Reactive )模型和前摄式( Proactive )模型:
传统的 select / epoll / kqueue 模型,以及 Java NIO 模型,都是典型的反应式模型,即应用代码对 I/O 描述符进行注册,然后等待 I/O 事件。当某个或某些 I/O 描述符所对应的 I/O 设备上产生 I/O 事件(可读、可写、异常等)时,系统将发出通知,于是应用便有机会进行 I/O 操作并避免阻塞。由于在反应式模型中应用代码需要根据相应的事件类型采取不同的动作,最常见的结构便是嵌套的 if {...} else {...} 或 switch ,并常常需要结合状态机来完成复杂的逻辑。
前摄式模型则恰恰相反。在前摄式模型中,应用代码主动地投递异步操作而不管 I/O 设备当前是否可读或可写。投递的异步 I/O 操作被系统接管,应用代码也并不阻塞在该操作上,而是指定一个回调函数并继续自己的应用逻辑。当该异步操作完成时,系统将发起通知并调用应用代码指定的回调函数。在前摄式模型中,程序逻辑由各个回调函数串联起来:异步操作 A 的回调发起异步操作 B , B 的回调再发起异步操作 C ,以此往复。 Mina 便是一个前摄式的异步 I/O 框架。
前摄式模型相较于反射式模型往往更加难以编程。然而在具有原生异步 I/O 支持的操作系统中(例如支持 IO Completion Port 的 Win32 系统),采用前摄式模型往往可以取得比反应式模型更佳的效率。在没有原生异步 I/O 支持的系统中,也可以使用传统的反应式 API 对前摄式模型予以模拟。在现代的软硬件系统中,使用 epoll 和 kqueue 的前摄式模型实现同样可以轻松解决 C10K 问题。前摄式模型的一个显著优势是在实现复杂逻辑的时候不需要借助于状态机。因为状态机已经隐含在由回调串联起来的异步操作链当中了。可以参考 Boost.Asio ,这是一个相当优秀的跨平台 C++ 前摄式 I/O 模型实现。
参考:(http://rhythm-zju.blog.163.com/blog/static/31004200801504351529 )
下图是 MINA
的架构图,
在图中的模块链中,IoService 便是应用程序的入口,相当于我们前面代码中的 IoAccepter,IoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来添加多个 IoFilter,这些 IoFilter 符合责任链模式并由 IoProcessor 线程负责调用。而 IoAccepter 在 ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。在上面的例子中,我们是这样使用 IoAccepter 的:
IoAcceptor acceptor = new
SocketAcceptor(); |
相当于我们使用了 Socket 通讯方式作为服务的接入,当前版本的 MINA 还提供了除 SocketAccepter 外的基于数据报文通讯的 DatagramAccepter 以及基于管道通讯的 VmPipeAccepter。另外还包括串口通讯接入方式,目前基于串口通讯的接入方式已经在最新测试版的 MINA 中提供。你也可以自行实现 IoService 接口来使用自己的通讯方式。
而在上图中最右端也就是 IoHandler,这便是业务处理模块。相当于前面例子中的 HelloHandler 类。在业务处理类中不需要去关心实际的通讯细节,只管处理客户端传输过来的信息即可。编写 Handler 类就是使用 MINA 开发网络应用程序的重心所在,相当于 MINA 已经帮你处理了所有的通讯方面的细节问题。为了简化 Handler 类,MINA 提供了 IoHandlerAdapter 类,此类仅仅是实现了 IoHandler 接口,但并不做任何处理。
一个 IoHandler 接口中具有如下一些方法(摘自 MINA 的 API 文档):
void exceptionCaught (IoSession session, Throwable cause) 当接口中其他方法抛出异常未被捕获时触发此方法 |
void messageReceived (IoSession session, Object message) 当接收到客户端的请求信息后触发此方法. |
void messageSent (IoSession session, Object message) 当信息已经传送给客户端后触发此方法. |
void sessionClosed (IoSession session) 当连接被关闭时触发,例如客户端程序意外退出等等. |
void sessionCreated (IoSession session) 当一个新客户端连接后触发此方法. |
void sessionIdle (IoSession session, IdleStatus status) 当连接空闲时触发此方法. |
void sessionOpened (IoSession session) 当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发 |
前面我们提到 IoService 是负责底层通讯接入,而 IoHandler 是负责业务处理的。那么 MINA 架构图中的 IoFilter 作何用途呢?答案是你想作何用途都可以。但是有一个用途却是必须的,那就是作为 IoService 和 IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceived,这个方法的第二个参数是一个 Object 型的消息,总所周知,Object 是所有 Java 对象的基础,那到底谁来决定这个消息到底是什么类型呢?答案也就在这个 IoFilter 中。在前面使用的例子中,我们添加了一个 IoFilter 是 new ProtocolCodecFilter(new TextLineCodecFactory()),这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给 IoHandler,因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。
而如果我们不提供任何过滤器的话,那么在 messageReceived 方法中的第二个参数类型就是一个 byte 的缓冲区,对应的类是 org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放在 IoHandler 中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得 IoHandler 不只是业务处理,还得充当协议解析的任务。
MINA自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilter(SSL加密)等。
参考:http://hi.baidu.com/jouby/blog/item/1e2a7507172a46c87b8947b3.html