Netty学习基础:BIO、NIO、AIO

其实我的重点呢,是来和大家一起学习接下来的Netty篇

然而嘞,这个Netty又不太合适直接讲,为啥呢,我们学习一门技术必须知道这门技术的由来的初衷是啥,对吧

先来给大家简单的介绍一下Netty是什么

Netty是一个提供异步事件驱动的网络应用程序框架,用以快速开发高性能、高可靠的网络服务器和客户端程序

Netty简化了网络程序的开发,属于BIO、NIO、AIO的演变中的产物,属于一种NIO框架

在我们平时使用的很多中间件中,很多底层通信都是采用的Netty,比如rocketmq、dubbo,这些我们最常见的底层通信都是用的netty,足以可见这个的性能是多么的优秀了

ok,接下来再来理解一下同步、异步、阻塞、非阻塞这四个概念

从简单的开始,我们以经典的读取文件的模型举例。(对操作系统而言,所有的输入输出设备都被抽象成文件。)

在发起读取文件的请求时,应用层会调用系统内核的I/O接口。

阻塞和非阻塞

如果应用层调用的是阻塞型I/O,那么在调用之后,应用层即刻被挂起,一处于等待数据返回的状态,直到系统内核从磁盘读取完数据并返回给应用层,应用层才用获得的数据进行接下来的其他操作。

如果应用层调用的是非阻塞I/O,那么调用后,系统内核会立即返回(虽然还没有文件内容的数据),应用层并不会被挂起,它可以做其他任意它想做的操作。(至于文件内容数据如何返回给应用层,这已经超出了阻塞和非阻塞的辨别范畴。)

这便是(脱离同步和异步来说之后)阻塞和非阻塞的区别。总结来说,是否是阻塞还是非阻塞,关注的是接口调用(发出请求)后等待数据返回时的状态。被挂起无法执行其他操作的则是阻塞型的,可以被立即「抽离」去完成其他「任务」的则是非阻塞型的。
在这里插入图片描述

同步和异步

阻塞和非阻塞解决了应用层等待数据返回时的状态问题,那系统内核获取到的数据到底如何返回给应用层呢?这里不同类型的操作便体现的是同步和异步的区别。

对于同步型的调用,应用层需要自己去向系统内核问询,如果数据还未读取完毕,那此时读取文件的任务还未完成,应用层根据其阻塞和非阻塞的划分,或挂起或去做其他事情(所以同步和异步并不决定其等待数据返回时的状态);如果数据已经读取完毕,那此时系统内核将数据返回给应用层,应用层即可以用取得的数据做其他相关的事情。

而对于异步型的调用,应用层无需主动向系统内核问询,在系统内核读取完文件数据之后,会主动通知应用层数据已经读取完毕,此时应用层即可以接收系统内核返回过来的数据,再做其他事情。

这便是(脱离阻塞和非阻塞来说之后)同步和异步的区别。也就是说,是否是同步还是异步,关注的是任务完成时消息通知的方式。由调用方盲目主动问询的方式是同步调用,由被调用方主动通知调用方任务已完成的方式是异步调用。
在这里插入图片描述

上面这几个概念大家一定要搞懂,这是基础,必须好好理解上面这些,才能真正理解netty的出处,这也是面试常被问到的点之一

总结一下

阻塞和非阻塞,关注的是发起请求之后等待数据返回时的状态,被挂起无法执行其他操作的是阻塞型的,可以立即去进行其他作业的是非阻塞型的

同步和异步,关注的是任务完成时的消息通知的方式,由调用方主动去询问的方式属于同步调用,而被调用方主动通知调用方该任务已完成的方式属于异步调用

这个在网上最常见的一个例子就是烧水的例子了,我也继续给大家啰嗦一下咯

老王烧水,老王把水放在炉子上,在这里干等着,啥也没有去做,并且需要随时看着水是否开了,这叫阻塞同步,阻塞是因为老王啥也不能去做,同步是因为水开他得自己看着

老王后来学精了,不在这里傻等着了,把水放在炉子上之后,然后就去开了一把紧张又刺激的lol手游,这叫非阻塞同步,非阻塞是因为老王在等水期间自己打游戏了,同步是因为水开他还是得自己看着

后来,老王觉得自己看着水太麻烦了,于是买了个升级版的水壶,牛了啊,这个水壶把水煮开了之后,会吹哨,哎

老王不需要每隔几分钟就去看一眼水是否开了,只需要听这个哨声即可,做水期间可以打游戏,并且水开了还会主动通知老王,这就是异步非阻塞,非阻塞就是因为老王可以去玩游戏,异步就是水壶的那个哨子

这下大家应该很好理解了吧!

接下来继续看BIO、NIO、AIO

在这里插入图片描述

Socket 网络通信过程简单来说分为下面 4 步:

建立服务端并且监听客户端请求

客户端请求,服务端和客户端建立连接

两端之间可以传递数据

关闭资源

传统的阻塞式通信BIO流程

BIO就是属于最传统的一种阻塞同步的通信方式,也是属于最简单的一种,使用起来比较方便,但是处理并发能力低,通信比较耗时

服务器会通过一个线程负责监听客户端请求和为每一个客户端创建一个新的线程进行链路的处理,属于一种典型的请求应答模式,若客户端数量增加,则需要频繁的创建和销毁线程,会给服务器增加很大的压力

服务器提供IP地址和监听的端口,客户端通过TCP的三次握手和服务器建立连接通信,连接成功之后,双方进行通过,之后通过四次挥手进行断开连接

即使用线程池的方式来改进新增加线程,这也是属于一种伪异步IO,这样实现能够为少数的客户端提供服务,如果客户端并发量足够多,还是会因为线程池满导致OOM的问题
在这里插入图片描述

给大家看一个简单的Demon

public class SocketServer {
   
    public static void main(String[] args) throws IOException {
   
        SocketServer socketServer = new SocketServer();
        socketServer.start(9000);
    }

    public void start(int port) {
   
        //1.创建 ServerSocket 对象并且绑定一个端口       
        try (ServerSocket server = new ServerSocket(port);) {
   
            System.out.println(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值