a Netty是基于Java的NIO实现的,对各种API进行统一封装。 b 基于事件模型,我们可以在对应事件编码自己业务。让开发者聚焦业务。 c 高度可定制线程模型,单线程,一个或者多个线程池。 d Netty只依赖JDK底层api。 e 在通信方面,减少不必要内存拷贝,提高性能。 f 在安全方面,完整的SSL/TLS和StartTLS。
Netty相对于NIO有什么优势?
a 对NIO中的API进行封装,使用简单。 b 写出高质量的NIO程序,需要多线程和网络编程的知识积累。 c NIO可靠性差,如:客户端从连、网络闪退、半包读写、失败缓存等问题。 d NIO会导致Selector空轮询,最终导致CPU100%,jdk1.7仍然会有这个问题,只是发送概率变低了。 21.2 Netty的架构是什么?
核心(Core)
a 可扩展的事件模型。 b 统一的通信api(无论是http还是socket都使用同意的api)。 c 零拷贝机制与字节缓冲区。
传输服务(Transport Services)
a 支持socket和datagram(数据报)。 b 支持http协议。 c In-VM Pipe(管道协议)。
协议支持(Protocol Support)
a http 以及 websocket。 b SSL 安全套接字协议⽀持。 c Google Protobuf (序列化框架)。 d ⽀持zlib、gzip压缩。 e ⽀持⼤⽂件的传输。 f RTSP(实时流传输协议,是TCP/IP协议体系中的⼀个应⽤层协议)。 g ⽀持⼆进制协议并且提供了完整的单元测试。 上面已经对Netty有个简单的认识,也了解使用Netty的好处。下面从IO模型和Reactor模型这两个角度来刨析使用Netty的好处。
a 客户端的并发数和服务端的线程数是一样多,随着并发量增加服务端线程数增加,服务端性能下降。 b 当连接创建后,该线程没有操作,会进行堵塞,不会释放线程。极大浪费服务器资源。
2.1.2 NIO模型
1. 对上图组件解释
a Buffer:是缓冲区、底层通过数组实现。在NIO中所有的读写操作都是基于Buffer的。Java基本类型除了boolean都有缓冲区对象。
b Channel:通常叫为通道,用于连接客户端和服务端。是双向的,可以读也可以写。
c Selector:通常叫多路复用器,用于找出注册其上的发生读和写的channel。原理如下: Selector不断轮询其上面的Channel,Channel发生读或者写,就会被Slector挑选出来。然后通过SelectionKey获取就绪Channel集合,进行IO读写操作。 2. 对上图进行分析
a 完成事件的注册和传递,需要操作系统底层提供大量支持。 b Windows 系统下通过 IOCP 实现了真正的异步 I/O。但是目前高并发系统都是部署到Linux上。 c Linux系统支持AIO模型不稳定。该系统下异步都是以NIO实现的。 上文介绍IO模型的三种情况:BIO模型、NIO模型、AIO模型。因为AIO模型是依赖操作系统底层,而且Linux支持不稳定,所以只需对其有个简单认识。NIO相对于BIO减少了堵塞和线程开销。42.2 常见Reactor模型
a Reactor 监听和分配事件 b Acceptor 处理客户端新连接,并分配请求到处理链中。 c Handler 将自身和事件绑定,执行读写操作(完成channel的读入,执行业务逻辑并将结果写道channel)。
2.2.1 单线程模型
上图说明
a 一个线程完成业务处理。 b Reactor相当于一个多路复用器,用于监听事件,并把发生的事件传递给Handler或者Acceptor。 c 如果是建立连接事件,Reactor传递给Acceptor。如果是读写事件,Reactor传给Handler。 1. 优点
a 优点 结构简单、单线程完成,没有进程通信问题。对一些业务场景简单,对性能要求不高的应用场景。 2. 缺点
a 发挥不了服务器多核优势
b 客户端连接过多导致客户端连接多,Reactor线程负载过重。导致客户端连接超时, 最终导致大量信息积压。性能低。