我一直认为对于java的学习,掌握基础的性价比要远远高于使用框架,而基础知识中对于网络相关知识的掌握也是重中之重。对于一个java程序来讲,不管是工做中仍是面试,对于Netty的掌握都是及其重要的。因此博主下定决心深度的学习一下Netty而且作下笔记与心得,供你们一块儿学习探讨。java
Netty的卓越之处在于它是一个高性能、异步事件驱动的NIO框架,目前不少著名的开源框架都使用Netty做为底层的通讯框架,如Haddop、storm等。linux
好的废话很少说,咱们直接进入主题。面试
Linux的内核将全部的外部设备都看做一个文件来操做。好比操做一个文件的时候,linux会获得这个文件的文件描述符(fd),经过这个描述符来操做文件。socket的读写尽管不是本地的文件,可是Linux是经过一个相似文件描述符,称为socket描述符(socketfd)来操做网络数据的。描述符就是一个数字,它指向内核中的一个结构体(文件的路径,数据区等一些属性)。缓存
这是咱们最最多见的I/O模型,例如咱们日常编写java程序所用的读写文件都是阻塞的。什么意思呢?就是当程序执行到读/写这一步操做的时候不会继续往下执行代码,而是等到读/写的操做执行完毕。
套接字接口的状况则是,进程准备接受或发送的数据的时候,,会向内核调用recvfrom()方法,这个方法会一直阻塞,直到数据包接受或发送完毕,或者发生错误的时候才返回,在此期间一直等待。网络
区别于阻塞I/O模型,当咱们接受或发送数据包的时候不会阻塞的等待,而是经过一个循环检查套接口的状态,若是缓存区中没有数据,当进程调用recvfrom()方法的时候,内核直接返回一个EWOULDBLOCK错误。当有数据来的时候,才继续后续操做。框架
这个是Netty底层所使用的 I/O模型,相似于一个小区的物业,管理着全部住户的快递,当有快递小哥来送快递的时候快递小哥不用一层一层爬到用户家中,而是将快递存放到物业。再由物业来通知用户取快递。异步
原理是Linux提供 select/poll方法,经过启动一个进程来管理全部链接的描述符,经过顺序扫描全部描述符是否为就绪状态。可是这种方式有一个弊端,那就是同时管理的描述符有上限,通常来讲最多支持1024个。因此linux在后来提供了pselect/epoll方法,区别于select/poll方法:socket
循环扫描的时候只扫描活跃的文件,所支持的描述符管理上线为操做系统的最大文件句柄数,好比1GB内存的机器数量大约是10万个句柄左右,所以如今基本上都是使用的后者。函数
因为epoll每次都只是扫描活跃的socket,而且在大多数状况下,只有少部分的socket是活跃的,所以epoll效率会高不少,可是若是在一个高速的LAN环境下,epoll并不会比select/poll的效率高太多;相反相率可能还会稍稍下降。性能
每次接受数据的时候内核须要把数据从内核缓存复制到用户缓存,这一步内存复制实际上是很下降效率的,epoll是经过内核和用户空间mmap同一块内存来实现的。
epoll的API更加简单。
首先开启套接口信号驱动,并经过系统调用sigaction执行一个信号处理函数,而后进程继续工做。当数据准备就绪的时候,就为该进程生成一个SIGIO信号,经过信号回调通知引用程序来读取数据。
这种模型与信号驱动模型的主要区别就是:信号驱动I/O模型由内核通知进程能够开始一个I/O操做了。而异步I/O模型这个逼就更猛了,直接通知进程,劳资已经帮你搞完了。
这五种模型每一种都有很深的学问,博主在这里只是用我本身所理解的知识来简单的介绍一下这五种模型,可是若是你对其中的I/O模型有浓厚的兴趣,能够自行对每一种模型进行进一步深度学习。这里我推荐I/O复用模型,由于Netty的底层就是使用的该模型。