java原生各种IO和Netty框架的对比

异步非阻塞I/O

JDK 1.4的NIO框架经常被称为异步非阻塞I/O,但是,如果严格按照UNIX网络编程模型和JDK的实现进行区分,实际上它只能被称为非阻塞I/O,不能叫异步非阻塞I/O。

JDK 1.4和1.5 update10版本之前,JDK的Selector是基于select/poll模型实现的,它是基于I/O复用技术的非阻塞I/O,不是异步I/O。
在JDK 1.5 update10和Linux core2.6以上版本,Sun优化了Selctor的实现,它在底层使用epoll替换了select/poll,上层的API并没有变化,可以认为是JDK NIO的一次性能优化,但是它仍旧没有改变I/O的模型。

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

NIO类库支持非阻塞读和写操作,相比于之前的同步阻塞读和写,它是异步的,因此很多人习惯于称NIO为异步非阻塞I/O。

多路复用器Selector

Java NIO1的实现关键是多路复用I/O技术,多路复用的核心是通过Selector来轮询注册在其上的Channel,当发现某个或者多个Channel处于就绪状态后,从阻塞状态返回就绪的Channel的选择键集合,进行I/O操作。
由于多路复用器是NIO实现非阻塞I/O的关键,它又是主要通过Selector实现的,所以将Selector翻译为多路复用器更合适。

伪异步I/O

伪异步I/O的概念完全来源于实践。
在JDK NIO编程没有流行之前,为了解决Tomcat通信线程同步I/O导致业务线程被挂住的问题,大家想到了一个办法:在通信线程和业务线程之间做个缓冲区,这个缓冲区用于隔离I/O线程和业务线程间的直接访问,这样业务线程就不会被I/O线程阻塞。
而对于后端的业务侧来说,将消息或者Task放到线程池后就返回了,它不再直接访问I/O线程或者进行I/O读写,这样也就不会被同步阻塞。
类似的设计还包括前端启动一组线程,将接收的客户端封装成Task,放到后端的线程池执行,用于解决一连接一线程问题。

不同I/O模型对比

java原生各种IO和Netty框架的对比_第1张图片

选择Netty的理由

开发出高质量的NIO程序并不是一件简单的事情,除去NIO固有的复杂性和BUG,作为一个NIO服务端,还需要处理网络的闪断、客户端的重复接入、客户端的安全认证、消息的编解码、半包读写等情况。
从可维护性角度看,由于NIO采用了异步非阻塞编程模型,而且是一个I/O线程处理多条链路,它的调试和跟踪非常麻烦,特别是生产环境中的问题,我们无法进行有效的调试和跟踪,往往只能靠一些日志来辅助分析,定位难度很大。

不选择Java原生NIO编程的原因

(1)NIO的类库和API繁杂,使用麻烦,需要熟练掌握SelectorServerSocketChannelSocketChannelByteBuffer等。
(2)需要具备其他的额外技能做铺垫,例如熟悉Java多线程编程。这是因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序。
(3)可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题,NIO编程的特点是功能开发相对容易,但是可靠性能力补齐的工作量和难度都非常大。
(4)JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。官方声称在JDK 1.6版本的update18修复了该问题,但是直到JDK 1.7版本该问题仍旧存在,只不过该BUG发生概率降低了一些而已,它并没有得到根本性解决。

不建议直接使用JDK的NIO类库

Netty既可以作为客户端也可以作为服务端,同时支持UDP和异步文件传输,功能非常强大。

为什么选择Netty

健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的。

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

你可能感兴趣的:(java原生各种IO和Netty框架的对比)