Netty简述

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

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

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

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

先来简单看一下Netty官网的架构图:

从图中可以看出,Netty的架构分为三块,核心(Core),通信服务(Transport Services)还有各种协议(Protocol Support)。我们想象将来要学习的内容都和这些有关系。通过架构图对其有个基本印象。

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)

来看下面的图片:

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

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

阻塞式 I/O 模型

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

非阻塞式 I/O 模型

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

I/O 复用模型

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

信号驱动式 I/O 模型

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

异步 I/O模型

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

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

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

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

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

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

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

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

同步VS异步

lPOSIX标准将同步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复用模型。

推荐书籍《Unix网络编程》,推荐理由:网络编程的经典之作,经历了十年左右,内容基本变化不大,原理性书籍,是网络编程的必看之书。

本文由博客一文多发平台 OpenWrite 发布!

Netty快速入门(01)Linux I/O模型介绍的更多相关文章

  1. Netty快速入门(05)Java NIO 介绍-Selector

    Java NIO Selector Selector是Java NIO中的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读.可写.如此可以实现单线程管理多个channels,也就是 ...

  2. Netty快速入门(08)ByteBuf组件介绍

    前面的内容对netty进行了介绍,写了一个入门例子.作为一个netty的使用者,我们关注更多的还是业务代码.也就是netty中这两种组件: ChannelHandler和ChannelPipeline ...

  3. Netty快速入门(03)Java NIO 介绍-Buffer

    NIO 介绍 NIO,可以说是New IO,也可以说是non-blocking IO,具体怎么解释都可以. NIO 1是在JSR51里面定义的,在JDK1.4中引入,因为BolckingIO不支持高并 ...

  4. Netty快速入门(09)channel组件介绍

    书接上回,继续介绍组件. ChannelHandler组件介绍 ChannelHandler组件包含了业务处理核心逻辑,是由用户自定义的内容,开发人员百分之九十的代码都是ChannelHandler. ...

  5. Netty快速入门(06)Netty介绍

    前面简单的介绍了Java I/O 和NIO,写了示例程序. Java I/O是阻塞的,为了让它支持多个并发,就要针对每个链接启动线程,这种方式的结果就是在海量链接的情况下,会创建海量的线程,就算用线程 ...

  6. 网络应用框架Netty快速入门

    一 初遇Netty Netty是什么? Netty 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能.可扩展协议的服务器和客户端 ...

  7. Netty快速入门(10)Reactor与Netty

    Reactor模式 Reactor是1995年由道格拉斯提出的一种高性能网络编程模式.由于好多年了,当时的一些概念与现在略有不同,reactor模式在网络编程中是非常重要的,可以说是NIO框架的典型模 ...

  8. ETCD快速入门-01 ETCD概述

    1.ETCD概述 1.1 ETCD概述     etcd是一个高可用的分布式的键值对存储系统,常用做配置共享和服务发现.由CoreOS公司发起的一个开源项目,受到ZooKeeper与doozer启发而 ...

  9. docker快速入门01——docker安装与简单应用

    1.docker简介 Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化 ...

随机推荐

  1. WPF 之 DataTemplate 实例(摘抄)

     

  2. 2018-9-1-win2d-画出好看的图形

    title author date CreateTime categories win2d 画出好看的图形 lindexi 2018-09-01 16:25:40 +0800 2018-2-13 17 ...

  3. Mac下SVN基本操作和常见错误

    一.基本操作 1  从服务器上下载代码 svn checkout http://xxx.xxx.xxx/xxx 2  获取最新的代码 svn update 3  提交代码 svn commit -m ...

  4. win10 uwp 在 VisualStudio 部署失败,找不到 Windows Phone 可能的原因

    在我使用 VisualStudio 调试的时候,发现我插入了手机,但是 VisualStudio 在部署的时候找不到手机. 可能的原因是 手机禁用了连接,第二个原因是可能手机驱动没正确让 Visual ...

  5. linux进程互斥等待

    我们已经见到当一个进程调用 wake_up 在等待队列上, 所有的在这个队列上等待的进程 被置为可运行的. 在许多情况下, 这是正确的做法. 但是, 在别的情况下, 可能提前知道 只有一个被唤醒的进程 ...

  6. Command failed: git -c core.longpaths=true config --get remote.origin.url

    「Unable to Connect to GitHub.com For Cloning」 Error: Command failed: git -c core.longpaths=true conf ...

  7. webpack+babel+react+antd技术栈的基础配置

    webpack+babel+react+antd技术栈的基础配置 前段时间使用webpack+babel+react+antd做了一套后台管理系统,刚开始被一大堆的新知识压的喘不过气来,压力挺大的.还 ...

  8. JQ绑定事件的叠加和解决,index()方法的坑

    JQ绑定事件的叠加和解决,index()方法的坑 前言 在做过几个不大不小的项目后,发现技术这种东西,必须要多多实践,才能发现各种问题,理论的知识掌握的再好终究是纸上谈兵. 因此目前感觉有两点是必须要 ...

  9. git 上传当前分支

    因为我现在的分支是的名很长,每次需要上次当前分支需要写很多代码,是不是有很简单方法上传当前分支. 如果要上传一个分支到仓库 origin 那么就需要使用下面的命令 git push origin 分支 ...

  10. 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)

    牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...