Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。
2、NIO入门
首先我们看一下基于同步线程阻塞IO(BIO)的线程模型图
从上图可以看出同步阻塞IO(BIO)存在以下几个问题:
•最大的问题就是缺乏弹性伸缩能力,服务端线程和客户端并发访问数量呈1:1的正比关系;
•性能差:频繁的线程上下文切换导致CPU利用率不高;
•可靠性差:由于所有的 IO 操作都是同步的,所以业务线程只要进行 IO 操作,也会存在被同步阻塞的风险,这会导致系统的可靠性差,依赖外部组件的处理能力和网络的情况。
采用非阻塞 IO(NIO)之后,同步阻塞 IO 的三个缺陷都将迎刃而解:
•Nio 采用 Reactor 模式,一个 Reactor 线程聚合一个多路复用器 Selector,它可以同时注册、监听和轮询成百上千个 Channel,一个 IO 线程可以同时并发处理N个客户端连接,线程模型优化为1:N(N < 进程可用的最大句柄数)或者 M : N (M通常为 CPU 核数 + 1, N < 进程可用的最大句柄数);
•由于 IO 线程总数有限,不会存在频繁的 IO 线程之间上下文切换和竞争,CPU 利用率高;
•所有的 IO 操作都是异步的,即使业务线程直接进行 IO 操作,也不会被同步阻塞,系统不再依赖外部的网络环境和外部应用程序的处理性能。
由于切换到 NIO 编程之后可以为系统带来巨大的可靠性、性能提升,所以,目前采用 NIO 进行通信已经逐渐成为主流。
其次我们看下异步IO(NIO)的服务端和客户的工作时序图:
JDK NIO 服务端通信时序图
JDK NIO 服务端通信序列图
JDK NIO 客户端通信时序图
JDK NIO 客户端通信时序图
不选择JAVA原生NIO编程的原因:
(1)NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。
(2)需要具备其他的技能做铺垫,例如熟悉JAVA多线程编程,这是因为NIO编程设计到Reactor模式,你必须对多线程和网络编程特别熟悉,才能编写出高质量的NIO程序。
(3)可靠性能补齐,工作量非常大。例如客户端面临断链重连、网路闪断、半包读写和失败缓存等问题。
(4)JDK NIO的BUG,例如臭名昭著的epoll bug,它导致Selector的空轮巡,最终导致CPU 100% 。
为什么选择netty
Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可扩展性和可定制性在同类型框架中是首屈一指的,它已经得到成百上千的商用项目验证,例如Hadoop的RPC框架avro使用Netty作为底层的通讯框架。很多其他业界的主流RPC框架也使用了Netty来构建共性能的异步通讯能力。
Netty有如下几个优点
API使用简单开发门槛低;
功能强大,预置了多种编码功能,支持多种主流协议;
定制功能强,可以通过ChannelHandler对通信框架进行灵活的扩至;
性能高,通过和其他业界主流的NIO框架对比,Netty的综合性能最优;
成熟、稳定,Netty修复了所有的已知JDK NIO的BUG;
社区活跃,版本迭代周期短,发现BUG可以及时的被修复。