Netty — 核心组件与模型
📋 本文节选自《Netty 面试题》,返回 查看全部章节
1. Netty
最流行的 NIO 框架,由 JBOSS 提供的,整合了FTP,SMTP,HTTP协议
1、 API简单;
2、 成熟稳定;
3、 社区活跃·;
4、 经过大规模验证(互联网、大数据、网络游戏、电信通信);
Elasticsearch、Hadoop 子项目 avro项目、阿里开源框架 Dubbo、使用 Netty
2. BIO
优点:模型简单,编码简单缺点:性能瓶颈,请求数和线程数 N:N 关系高并发情况下 ,CPU 切换线程上下文损耗大案例:Tomcat 7之前,都是 BIO,7 之后是 NIO改进:伪 NIO,使用线程池去处理逻辑
3. IO 模式
同步阻塞:丢衣服->等洗衣机洗完->再去晾衣服同步非阻塞:丢衣服->去做其他事情,定时去看衣服是否洗完->洗完后自己去晾衣服异步非阻塞:丢衣服-> 去做其他事情不管了,衣服洗好会自动晾好,并且通知你晾好了
4. 五种 I/O 模型
五种I/O 模型:阻塞 IO、非阻塞 IO、多路复用 IO、信号驱动 IO、异步 IO,前 4 种是同步 IO,在内核数据copy 到用户空间时是阻塞的
5. 阻塞 IO
![ ][nbsp]
6. 非阻塞 IO
![ ][nbsp 1]
7. IO 多路复用
![ ][nbsp 2]核心:可以同时处理多个 connection,调用系统 select 和 recvfrom函数每一个socket 设置为 nonblocking 阻塞是被 select 这个函数 block 而不是 socket阻塞缺点:连接数不高的情况下,性能不一定比多线程+ 阻塞 IO 好(多调用一个select 函数)
8. 信号驱动
![ ][nbsp 3]
9. 异步 IO
采用Future-Listener机制
![ ][nbsp 4]
IO操作分为 2 步:
1、 发起IO请求,等待数据准备;
2、 实际的IO操作,将数据从内核拷贝到进程中;阻塞 IO、非阻塞 IO 区别在于发起 IO 请求是否被阻塞同步 IO、异步 IO 在于实际的 IO 读写是否阻塞请求进程阻塞非阻塞是线程的状态同步和异步是消息的通知机制同步需要主动读写数据,异步不需要主动读写数据同步 IO 和异步 IO 是针对用户应用程序和内核的交互
10.IO 多路复用
I/O是指网络 I /O ,多路指多个 TCP 连接,复用指一个或几个线程。简单来说:就是使用一个或者几个线程处理多个 TCP 连接,最大优势是减少系统开销,不必创建过多的线程进程,也不必维护这些线程进程
11. select
文件描述符 writefds、readdfs、exceptfds30w个连接会阻塞住,等数据可读、可写、出异常、或者超时返回select 函数正常返回后,通过遍历 fdset整个数组才能发现哪些句柄发生了事件,来找到就绪的描述符fd,然后进行对应的 IO操作,几乎在所有的平台上支持,跨平台支持性好缺点:
1、 select采用轮询的方式扫描文件描述符,全部扫描,随着文件描述符FD数量增多而性能下降;
2、 每次调用slect(),需要把fd集合从用户态拷贝到内核态,并进行遍历(消息传递都是内核到用户;空间)
3、 最大缺陷就是单个进程打开的FD有限制,默认是1024;
12. poll
基本流程和 select差不多,处理多个描述符也是轮询,根据描述符的状态进行处理,一样需要把fd集合从用户态拷贝到内核态,并进行遍历。区别是poll 没有最大文件描述符限制(使用链表方式存储fd)
13. epoll
没有描述符限制,用户态拷贝到内核态只需要一次使用事件通知,通过epoll_ctl注册fd,一旦该fd 就绪,内核就采用callback机制激活对应的fd优点:
1、 没有fd限制,所支持的FD上限是操作系统的最大文件句柄数(65535),1G内存大概支持10W;句柄,支持百万连接的话,16G 内存就可以搞定
2、 效率高,使用回调通知而不是轮询方式,不会随着FD数目增加效率下降;
3、 通过callback机制通知,内核和用户空间mmap同一块内存实现;缺点:编程模型比 select / poll 复杂linux内核核心函数
4、 epoll_create()系统启动时,会向linux内核申请一个文件系统,b+树,返回epoll对象,也是一个;fd
5、 epoll_ctl()操作epoll对象,在这个对象里面修改添加删除对应的链接fd,绑定一个callback函数;
6、 epoll_wait()判断并完成对应的IO操作;例子:100W 个连接,1W 个活跃,在 select ,poll,epoll中怎么样表现select :不修改宏定义,需要 1000 个进程才能支持 100W 连接poll:100W连接,遍历都响应不过来,还有空间的拷贝消耗大量的资源epoll: 不用遍历fd,不用内核空间和用户空间数据的拷贝如果 100W 个连接中,95W 活跃,则 poll 和 epoll差不多
14. Java的i/o
1、 jdk1.4之前是采用同步阻塞模型(BIO);大型服务一般采用 C/C++,因为可以直接操作系统提供的异步 IO(AIO)
2、 jdk1.4之后推出NIO,支持非阻塞IO,jdk1.7升级推出NIO2.0,提供了AIO功能,支持文件和网络;套接字的异步 IO
15. Netty 线程模型和 Reactor 模式
Reactor模式(反应器设计模式),是一种基于事件驱动的设计模式,在事件驱动的应用中,将一个或者多个客户的请求进行分离和调度。在事件驱动的应用中,同步地,有序地处理接受多个服务请求。属于同步非阻塞 IO优点:
1、 响应快,不会因为单个同步而阻塞,虽然reactor本身是同步的;
2、 编程相对简单,最大程度避免复杂的多线程以及同步问题,避免了多线程、进程切换开销;
3、 可扩展性,可以方便的通过reactor实例个数充分利用CPU资源;缺点:
4、 相对复杂,不易于调试;
5、 reactor模式需要系统底层的支持比如java中的selector支持,操作系统select系统调用支持;
16. Reactor 单线程模型
1、 作为NIO服务器,接受客户端TCP连接,作为NIO客户端,向服务端发起TCP连接;
2、 服务端读请求数据并响应,客户端写请求并读取响应;场景:对应小业务则适合,编码简单,对于高负载,高并发不合适。一个 NIO 线程处理太多请求,负载很高,并且响应变慢,导致大量请求超时,万一线程挂了,则不可用