Java IO编程全解(六)——4种I/O的对比与选型

  转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html html

  前面讲到:Java IO编程全解(五)——AIO编程前端

  为了防止因为对一些技术概念和术语的理解或者叫法不一致而引发歧义,这里对涉及到的专业术语或者技术用语作下声明:若是它们与其余一些地方的称呼不一致,请以本解释为准。编程

异步非阻塞I/O后端

  不少人喜欢将JDK1.4提供的NIO框架成为异步非阻塞I/O,可是,若是严格按照UNIX网络编程模型和JDK的实现进行区分,实际上它只能被称为非阻塞I/O,不能叫异步非阻塞I/O。在早期的JDK1.4和1.5 update10版本以前,JDK的Selector基于select/poll模型实现,它是基于I/O复用技术的非阻塞I/O,不是异步I/O。在JDK1.5 update10和Linux core2.6以上版本,Sun优化了Selector实现,它在底层使用epoll替换了select/poll,上层的API并无变化,能够认为是JDK NIO的一次性能优化,可是它仍旧没有改变I/O的模型。缓存

  由JDK1.7提供的NIO 2.0,新增了异步的套接字通道,它是真正的异步I/O,在异步I/O操做的时候能够传递信号变量,当操做完成以后会回调相关的方法,异步I/O也被称为AIO。安全

  NIO类库支持非阻塞读和写操做,相比于以前的同步阻塞读和写,它是异步的,NIO类库支持非阻塞读和写操做,相比于以前的同步阻塞读和写,它是一部的,所以不少人习惯称NIO为异步非阻塞I/O,包括不少介绍NIO编程的书籍也沿用了这个说法。为了符合你们的习惯,这里也会将NIO称为异步非阻塞I/O或者非阻塞I/O。请你们理解,不要过度纠结在一些技术术语的咬文嚼字上。性能优化

多路复用器Selector 服务器

  几乎全部的中文技术书籍都将Selector翻译为选择器,可是实际上我认为这样的翻译并不恰当,选择器仅仅是字面上的意思,体现不出Selector的功能和特色。微信

  前面介绍过Java NIO的实现关键是多路复用I/O技术,多路复用的核心就是经过Selector来轮询注册在其上的Channel,当发现某个或者多个Channel处于就绪状态后,从阻塞状态返回就绪的Channel的选择键集合,进行I/O操做。因为多路复用器是NIO实现非阻塞I/O的关键,它又是主要经过Selector实现的,因此这里将Selector翻译为多路复用器,与其余技术书籍所说的选择器是同一个东西,请你们了解。网络

伪异步I/O

  伪异步的概念彻底来源于实现。在JDK NIO编程没有流行以前,为了解决Tomcat通讯线程同步I/O致使业务线程被挂住的问题,你们想到了一个办法:在通讯线程和业务线程以前作个缓冲区,这个缓冲区用于隔离I/O线程和业务线程间的直接访问,这样业务线程就不会被I/O线程阻塞。而对于后端的业务侧来讲,将消息或者Task放到线程池后就返回了,它再也不直接访问I/O线程或者进行I/O读写,这样就不会被同步阻塞。相似的设计还包括前端启动一组线程,将接收到的客户端封装成Task,放到后端的线程池执行,用于解决一链接一线程问题。像这样经过线程池作缓冲区的作法,这里习惯于称它为伪异步I/O,而官方并无伪异步I/O这种说法,请你们注意。

1. 不一样I/O模型对比

  不一样的I/O模型因为线程模型、API等差异很大,因此用法的差别也很是大。

  实际开发中,具体选择什么样的I/O模型或者NIO框架,彻底基于业务的实际应用场景和性能诉求,若是客户端并发链接数很少,周边对接的网元很少,服务器的负载也不重,那就彻底不必选择NIO作服务器;若是是相反状况,那就要考虑选择合适的NIO框架进行开发。

2.选择Netty的理由

  开发出高质量的NIO程序并非一件简单的事情,除去NIO固有的复杂性和BUG不谈,做为一个NIO服务器,须要可以处理网络的闪断、客户端的重复接入、客户端的安全认证、消息的编解码、半包读写等状况,若是你没有足够的NIO编程经验积累,一个NIO框架的稳定每每须要半年甚至更长的时间。更为糟糕的是,一旦在生产环境中发生问题,每每会致使跨节点的服务调用中断,严重的可能会致使整个集群环境都不可用,须要重启服务器,这种非正常停机会带来巨大的损失。

  从可维护性角度看,因为NIO采用了异步非阻塞编程模型,并且是一个I/O线程处理多条链路,它的调试和跟踪很是麻烦,特别是生产环境中的问题,咱们没法进行有效的调试和跟踪,每每只能靠一些日志来辅助分析,定位难度很大。

2.1不选择Java原生NIO编程的缘由

  如今咱们总结一下咱们不建议开发者直接使用JDK的NIO类库进行开发,具体缘由以下。

  1. NIO的类库和API繁杂,使用麻烦,你须要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。
  2. 须要具有其余的额外技能作铺垫,例如熟悉Java多线程编程。这是由于NIO编程设计到Reactor模式,你必须对多线程和网络编程很是熟悉,才能编写出高质量的NIO程序。
  3. 可靠性能力补齐,工做量和难度都很是大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题,NIO编程的特色是功能开发相对容易,可是可靠性能力补齐的工做量和难度都很是大。
  4. JDK NIO的BUG,例如臭名昭著的epoll bug,它会致使Selector空轮询,最终致使CPU100%,官方声称在JDK1.6版本的update18修复了该问题,可是直到JDK1.7版本该问题仍旧存在,只不过该BUG发生频率下降了一些而已,它并无被根本解决。

  因为上述缘由,在大多数场景下,不建议你们直接使用JDK的NIO类库,除非你精通NIO编程或者有特殊的需求。在绝大多数的业务场景中,咱们可使用NIO框架Netty来进行NIO编程,它既能够做为客户端也能够做为服务端,同时支持UDP和异步文件传输,功能很是强大。

2.2为何选择Netty

  Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是数一数二的,它已经获得成百上千的商业项目验证,例如Hadoop的RPC框架avro使用Netty做为底层通讯框架;不少其余业界主流的RPC框架,也使用Netty来构建高性能的异步通讯能力。

  Netty的优势总结以下:

  • API使用简单,开发门槛低;
  • 功能强大,预置了多种编解码功能,支持多种主流协议;
  • 定制能力强,能够经过ChannelHandler对通讯框架进行灵活地扩展;
  • 性能高,经过与其余业界主流的NIO框架对比,Netty的综合性能最优;
  • 成熟、稳定,Netty修复了已经发现的全部JDK NIO BUG,业务开发人员不须要再为NIO的BUG而烦恼;
  • 社区活跃,版本迭代周期短,发现的BUG能够被及时修复,同时,更多的新功能会加入;
  • 经历了大规模的商业应用考验,质量获得验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业获得成功商用,证实了它已经彻底可以知足不一样行业的商业应用了。

  正是由于这些优势,Netty逐渐成为Java NIO编程的首选框架。

Netty(一)——Netty入门程序

若是此文对您有帮助,微信打赏我一下吧~

相关文章
相关标签/搜索