BIO、NIO和AIO的区别以及Netty 简介
要分清这三个,首先要分清这两组概念。
同步(Synchronization)和异步(Asynchronous)的方式
同步和异步都是基于应用程序所在操作系统处理IO事件所采用的方式,
比如同步:是应用程序要直接参与IO读写的操作。
异步:所有的IO读写交给搡作系统去处理,应用程序只需要等待通知。
举个通俗的例子:你打电话问书店老板有没有《分布式系统》这本书,
如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,
等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。
然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。
阻塞(Block)和非租塞(NonBlock)
阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,
当数据没有准备的时候阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否則一直等待在那里。
非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回不会等待。 如果数据已经准备好,也直接返回。
还是上面的例子,你打电话问书店老板有没有《分布式系统》这本书,
你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,
如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了,
当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。
BIO、NIO和AIO的区别
- BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理,线程开销大。伪异步IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源。
- NIO:一个请求一个线程,但客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
- AIO:一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
BIO是面向流的,NIO是面向缓冲区的;BIO的各种流是阻塞的。而NIO是非阻塞的;BIO的Stream是单向的,而NIO的channel是双向的。
Netty框架
Netty 是基于NIO,对NIO进行封装的高性能通信框架,很多著名的框架比如Dubbo、Spring5 的新特性Spring WebFlux 等底层都使用到Netty。
Netty的组件
- I/O:各种各样的流(文件、数组、缓冲、管道。。。)的处理(输入输出)。
- Channel:通道,代表一个连接,每个Client请对会对应到具体的一个Channel。
- ChannelPipeline:责任链,每个Channel都有且仅有一个ChannelPipeline与之对应,里面是各种各样的Handler。
- handler:用于处理出入站消息及相应的事件,实现我们自己要的业务逻辑。
- EventLoopGroup:I/O线程池,负责处理Channel对应的I/O事件。
- ServerBootstrap:服务器端启动辅助对象。
- Bootstrap:客户端启动辅助对象。
- ChannelInitializer:Channel初始化器。
- ChannelFuture:代表I/O操作的执行结果,通过事件机制,获取执行结果,通过添加监听器,执行我们想要的操作。
- ByteBuf:字节序列,通过ByteBuf操作基础的字节数组和缓冲区。