1. Netty简介
简而言之,Netty就是一个高性能、异步事件驱动的NIO框架,基于JAVA NIO提供的API实现。Netty是典型的Reactor模型结构。Reactor模式首先是事件驱动的。
2. 四种io的简单区别
通常io操作分为以下步骤:发起IO请求
和IO操作
。
如果发起IO请求被阻塞那就是阻塞IO
;如果不阻塞,那么就是非阻塞IO
。
如果IO读写阻塞请求进程,那么就是同步IO
,而操作系统帮你做完IO操作之后然后再通知io请求已完成,那么就是异步IO
。
3. 什么是BIO、NIO、AIO
BIO(同步阻塞IO)
当客户端有链接请求时服务端就会启动一个线程处理客户端的链接,一个链接就要启动一个线程,一个线程大致消耗1Mb的内存,当连接变多的时候就很耗性能。
BIO优点:
模型简单
编码简单
BIO缺点:
耗性能
BIO适用场景:
适用于连接数目比较小并且一次发送大量数据的场景
NIO(同步非阻塞IO)
客户端发送的连接请求都会注册到多路复用器上(selector),多路复用器轮询到连接有I/O请求时用一个或者少量线程去处理。selector类似一个观察者, socket没有请求的时候selector一直处于阻塞状态,等到有accept/read/write等事件发生时唤醒Selector,这时候就分配一个线程去处理。
NIO优点:
性能瓶颈高
NIO缺点:
模型复杂
编码复杂
有异常bug
空循环耗性能
要处理粘包、半包问题
NIO适用场景:
适合处理连接数目特别多,但是连接比较短(轻操作)的场景,Jetty,Mina,ZooKeeper等都是基于java nio实现。
AIO(异步非阻塞式IO)
在AIO中,客户端的io操作都是由系统完成的,完成后(读写完毕之后)然后才去通知服务器的,它无需一个线程去轮询有无请求。当进行读写操作时,只须直接调用API的read或write方法即可,读写都是异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。
AIO适用场景:
适用于连接数目多且连接比较长(重操作)的架构。
4. Netty线程模型
Netty是典型的Reactor模型结构,那么基于不同线程的Reactor模型,就有了不同的Netty线程模型。
可以分为三种模型:Reactor单线程模型
,Reactor多线程模型
,主从Reactor模型
。
1)Reactor单线程模型
在Reactor单线程模型中,Acceptor用于接收客户端的链接请求,生成对应的Handler,并向Reactor注册。Handler主要用于处理业务,比如io读写、编码解码、计算等等。Reactor线程采用异步非阻塞IO,Reactor线程负责分离套接字、处理链接请求、注册Handler、将Socket操作请求分发到对应的Handler去处理。在这个模式中当同一个客户端多次发送请求的时候是同一个Handler在处理,如果这个Handler异常或者处理过慢,那么后续的客户端请求就难以得到相应。
2)Reactor多线程模型
为了解决单线程模式读写压力的问题,Reactor多线程模型在读写方面增加了线程池,IO操作和非IO操作分开,操作IO的线程称为IO线程,非IO操作的线程称为工作线程。客户端的请求会直接被丢到线程池中,客户端发送请求也就不会堵塞了。Reactor多线程模型解决了读写性能问题,提高了整体性能,但是在用户量大量增加的时候, 一个Reactor可能出现性能不足的问题,Reactor又要处理链接请求又要处理读写操作。
3)主从Reactor模型
将Reactor分成两部分,mainReactor负责监听socket,接收新连接,并将建立的Handler分派给subReactor。subReactor负责多路分离已连接的socket,读写数据等操作。
4. Netty模块简单接收
1)Selector
Netty 基于 Selector 对象实现 I/O 多路复用,通过 Selector 一个线程可以监听多个连接的 Channel 事件。
2)NioEventLoop
一个NioEventLoop有一个线程和一个任务队列,支持异步提交执行任务,线程启动时会调用 NioEventLoop 的 run 方法,执行 I/O 任务和非 I/O 任务。
3)NioEventLoopGroup
主要管理 eventLoop 的生命周期,类似一个线程池,内部维护了一组线程,每个线程(NioEventLoop)负责处理多个 Channel 上的事件。
4)ChannelHandler
处理 I/O 事件或拦截 I/O 操作,并将其转发到其 ChannelPipeline中的下一个处理程序。
5)ChannelPipeline
它保存 ChannelHandler 的 List,用于处理或拦截 Channel 的入站事件和出站操作。