Netty 快速入门(01)Linux I/O模型介绍

Netty简述

Netty是一个高性能的网络编程框架

上面提到的几个关键的字眼,高性能,网络编程,框架。这些概括Netty的本质。

Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大的简化并TCP和UDP套接字服务器等网络编程。

“快速简便”并不意味着最终的应用程序会受到可维护性或性能问题的影响。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。因此,Netty成功地找到了一种在不妥协的情况下实现易于开发,性能,稳定性和灵活性的方法。

Linux I/O模型

在Linux中,将I/O模型分为五种类型:

  1. 阻塞式 I/O 模型
  2. 非阻塞式 I/O 模型
  3. I/O 复用
  4. 信号驱动式 I/O
  5. 异步 I/O

Linux中的I/O流程概括来说可以分为两步:

  1. 等待数据准备好(Waiting for the data to be ready)
  2. 从内核向进程复制数据(Copying the data from the kernel to the process)

file

上面的流程可以看出,首先是内核空间把数据从硬件(磁盘)中读到内核空间的缓冲区中,进行这一操作时,数据处于内核态,通过磁盘驱动器,把数据从磁盘读到内核缓冲区来。下一步是把数据从内核缓冲区拷贝到用户空间的缓冲区,数据由内核态变为用户态。

知识普及:Linux中的程序大致运行在两个空间,自己的程序运行在用户空间,用户空间的权限有限,相对的另外一个空间是内核空间,比如驱动程序或者一些核心的系统调用都是在内核空间完成的。我们的 I/O操作当在一个用户控件做系统调用的时候,数据会自动从用户态变到内核态来进行操作,完成了以后再从内核空间拷贝到用户空间。这种状态的切换是为了保证安全。比如我们在32位的操作系统中,大部分是4G的内存,一般前面一个G主要是内核态使用,后面三个G是用户态使用。

阻塞式I/O模型

 

file

阻塞式I/O是我们最常见的一种IO,当我们发起一个IO请求之后,开始进行系统调用,数据变为内核态,这两个阶段是一直处于阻塞的。数据开始从磁盘拷贝到内核空间,处理完成后再把内核空间拷贝到应用空间,数据变为用户态。这整个的过程涉及到的所有程序线程都是在等待状态。比如我们Java普通的Socket 编程,就是这样一个流程。整个过程中数据没有完成前,接收方都是出于等待状态,这就是阻塞式IO模型。明显可见效率不会高。

非阻塞式 I/O 模型

file

这种方式的特点是调用的时候不会等待(也就是不会阻塞),系统如果没有数据,就会立刻告诉你现在没有数据会立刻返回,然后由调用方自己去问现在有没有,如果没有就下次再问有没有,相当于不断去轮询结果,直到某个时刻被告知有结果了,这个时候数据已经从磁盘拷贝到内核空间了,数据也处于内核状态,就差最后从内核拷贝到用户空间,但是,从内核空间拷贝到用户空间,让数据从内核态变为用户态,这个过程在非阻塞式I/O模型中也是会阻塞的,所以效率也不会太高。

I/O复用模型

file

复用的意思是,系统一次去查看多个io的进度,看哪一个有结果,对于有结果的,就开始执行下面从内核空间拷贝到用户空间的操作,这个模型和上面非阻塞式I/O模型的区别是,非阻塞式I/O模型一次只看一个结果好了没有,而IO 复用模型一次可以查看多个,一次监控一批系统调用好了没有,这是复用模型的特点。在一定程度上,能提高效率。

信号驱动式I/O模型

file

在Linux系统中,有一种信号机制,也就是说调用方可以注册一个信号,当系统调用完成之后,可以通知这个信号,那注册信号的人就会知道这个请求已经完成了,这种信号机制应用在IO 当中就是信号驱动式IO。这样就不是查看结果是否好了,而是被通知一种方式。不过通知后,从内核态到用户态这个过程还是阻塞的。

异步I/O模型

file

这种模型是真正的纯异步的IO模型,当开始系统调用,数据从磁盘读到内核空间,并且从内核已经拷贝到了用户态之后,整个流程已经完成了,然后在进行回调,通知调用方。主要的区别在于不是在内核空间中完成了就通知,而是由内核空间到了用户空间后再通知,没有任何阻塞的过程,是一种更加彻底的异步IO。

 

各种I/O模型之间的比较

file

阻塞式IO就是发起调用之后,就一直阻塞,在等着,直到整个IO完成。在这个过程中,进程是不能干任何事情的。都在等待。

非阻塞式IO就是,进程会主动去问好了没,好了没,好了没。。。直到得到回复好了,然后发起读请求,把数据从内核空间拷贝到用户空间。这个过程是阻塞的。

IO复用模型,就是每次都查看多个结果好了没,如果发现n个当中有一两个有了结果,就返回,有结果的这些开始拷贝。

信号驱动式IO模型,就是等数据拷贝到内核空间再通知,前面这段时间可以做别的事情,等内核空间准备好了,通知,再把数据从内核空间拷贝到用户空间。

异步IO模型,就是发起调用后就彻底不管了,等数据好了后从内核空间拷贝到用户空间了,在进行通知,整个过程没有阻塞的步骤。

从比较重来看,异步IO从理论上来看是最好的,不存在任何阻塞的时间,系统资源理论上可以得到充分利用。

 

同步VS异步

IPOSIX标准将同步I/O和异步I/O定义为:

同步I/O操作:导致请求进程阻塞,直到I/O操作完成。

异步I/O操作:不导致请求进程阻塞。

从定义上看,只有最后的异步IO模型是真正的异步,前面四种都达不到真正的异步。但是目前来看,纯异步的IO一直都不太成熟,比较混乱,没有一个标准的解决方案。用的最多的还是IO复用模型,这个是目前为止比较成熟的一个模型。

在Java中,我们用的最多的Socket网络编程,就是阻塞式IO模型,后来的NIO就是IO复用模型,在Java中不支持信号驱动模型。Java的NIO2.0.也叫AIO,提供了纯异步的IO模型,但是现在的异步IO模型还不是很成熟,所以用的最多的就是NIO,也就是IO复用模型。

 

 

图文来源网络 如有侵权请联系删除。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值