大数跨境
0
0

阻塞IO 非阻塞IO 异步IO

阻塞IO 非阻塞IO 异步IO 二进制跳动
2023-12-05
1
导读:阻塞IO 非阻塞IO 异步IO 各显神通

Netty 的高性能架构,是基于一个网络编程设计模式 Reactor 进行设计的。现在,大多数与 I/O 相关的组件,都会使用 Reactor 模型,比如 Tomcat、Redis、Nginx 等,可见 Reactor 应用的广泛性。


Reactor 是 NIO 的基础。为什么 NIO 的性能就能够比传统的阻塞 I/O 性能高呢?我们首先来看一下传统阻塞式 I/O 的一些特点。


非阻塞 I/O 模型

其实,在处理 I/O 动作时,有大部分时间是在等待。比如,socket 连接要花费很长时间进行连接操作,在完成连接的这段时间内,它并没有占用额外的系统资源,但它只能阻塞等待在线程中。这种情况下,系统资源并不能被合理利用。


Java 的 NIO,在 Linux 上底层是使用 epoll 实现的。epoll 是一个高性能的多路复用 I/O 工具,改进了 select 和 poll 等工具的一些功能。在网络编程中,对 epoll 概念的一些理解,几乎是面试中必问的问题。


epoll 的数据结构是直接在内核上进行支持的,通过 epoll_create 和 epoll_ctl 等函数的操作,可以构造描述符(fd)相关的事件组合(event)。


这里有两个比较重要的概念:


fd 每条连接、每个文件,都对应着一个描述符,比如端口号。内核在定位到这些连接的时候,就是通过 fd 进行寻址的。


event 当 fd 对应的资源,有状态或者数据变动,就会更新 epoll_item 结构。在没有事件变更的时候,epoll 就阻塞等待,也不会占用系统资源;一旦有新的事件到来,epoll 就会被激活,将事件通知到应用方。



关于 epoll 还会有一个面试题,相对于 select,epoll 有哪些改进?


你可以这样回答:


epoll 不再需要像 select 一样对 fd 集合进行轮询,也不需要在调用时将 fd 集合在用户态和内核态进行交换;


应用程序获得就绪 fd 的事件复杂度,epoll 是 O(1),select 是 O(n);


select 最大支持约 1024 个 fd,epoll 支持 65535个;


select 使用轮询模式检测就绪事件,epoll 采用通知方式,更加高效。


Reactor 模式


模型 里面有四个主要元素:

Acceptor处理 client 的连接,并绑定具体的事件处理器;

Event具体发生的事件,比如图中sub的read、send等;

Handler执行具体事件的处理者,比如处理读写事件的具体逻辑;

Reactor将具体的事件分配(dispatch)给 Handler。


mainReactor负责监听处理新的连接,然后将后续的事件处理交给 subReactor;

subReactor对事件处理的方式,也由阻塞模式变成了多线程处理,引入了任务队列的模式。





面试官可能会问你:为什么我在使用 NIO 时,使用 Channel 进行读写,socket 的操作依然是阻塞的?NIO 的作用主要体现在哪里?


这时你可以回答:NIO 只负责对发生在 fd 描述符上的事件进行通知。事件的获取和通知部分是非阻塞的,但收到通知之后的操作,却是阻塞的,即使使用多线程去处理这些事件,它依然是阻塞的。


AIO 更近一步,将这些对事件的操作也变成非阻塞的。下面是一段典型的 AIO 代码,它通过注册 CompletionHandler 回调函数进行事件处理。这里的事件是隐藏的,比如 read 函数,它不仅仅代表 Channel 可读了,而且会把数据自动的读取到 ByteBuffer 中。等完成了读取,就会通过回调函数通知你,进行后续的操作。




不管怎么费尽心力,人会受伤的时候就会受伤。

村上春树





总结

BIO 的线程模型是一个连接对应一个线程的,非常浪费资源;


NIO通过对关键事件的监听,通过主动通知的方式完成非阻塞操作,但它对事件本身的处理依然是阻塞的;


AIO 完全是异步非阻塞的,但现实中使用很少。


使用 Netty 的多 Acceptor 模式和多线程模式,我们能够方便地完成类似 AIO 这样的操作。Netty 的事件触发机制使用了高效的 ET 模式,使得支持的连接更多,性能更高。


使用 Netty,能够构建响应式编程的基础,加上类似 Lambda 表达式这样的书写风格,能够完成类似 WebFlux 这样的响应式框架。响应式编程是一个趋势,现在有越来越多的框架和底层的数据库支持响应式编程,我们的应用响应也会更加迅速。


【声明】内容源于网络
0
0
二进制跳动
15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
内容 739
粉丝 0
二进制跳动 15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
总阅读97
粉丝0
内容739