I/O模型系列之三:IO通信模型BIO NIO AIO
一、传统的BIO
网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建立连接,如果连接建立成功,双方就可以通过网络套接字(Socket)进行通信。
在基于传统同步阻塞模型开发中,ServerSocket负责绑定IP地址,启动监听端口,Socket负责发起连接操作,连接成功之后,双方通过输入和输出流进行同步阻塞式通信。
BIO通信模型图
BIO的服务端通信模型:采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客户端,线程销毁。这就是典型的一请求一应答通信模型。
该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发访问量增加后,服务端的线程个数和客户端并发访问数呈1:1的正比关系,由于线程是JAVA虚拟机非常宝贵的系统资源,当线程数膨胀之后,系统的性能将急剧下降,随着并发访问量的继续增大,系统会发生线程堆栈溢出、创建新线程失败等问题,并最终导致进程宕机或者僵死,不能对外提供服务。
它的弊端有很多:
1.性能问题:一连接一线程模型导致服务端的并发接入数和系统吞吐量受到极大限制;
2.可靠性问题:由于I/O操作采用同步阻塞模式,当网络拥塞或者通信对端处理缓慢会导致I/O线程被挂住,阻塞时间无法预测;
3.可维护性问题:I/O线程数无法有效控制、资源无法有效共享(多线程并发问题),系统可维护性差;
二、伪异步IO编程
为了解决同步阻塞IO面临的一个链路需要一个线程处理的问题,后来有人对它的线程模型进行了优化,后端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大线程数N的比例关系,其中M可以远远大于N,通过线程池可以灵活的调配线程资源,设置线程的最大值,防止由于海量并发接入导致线程耗尽。 下面,我们结合连接模型图和源码,对伪异步IO进行分析,看它是否能够解决同步阻塞IO面临的问题。
伪异步IO模型图
采用线程池和任务队列可以实现一种叫做伪异步的IO通信框架,它的模型图如下:
当有新的客户端接入的时候,将客户端的Socket封装成一个Task(该任务实现java.lang.Runnable接口)投递到后端的线程池中进行处理,JDK的线程池维护一个消息队列和N个活跃线程对消息队列中的任务进行处理。由于线程池可以设置消息队列的大小和最大线程数,因此,它的资源占用是可控的,无论多少个客户端并发访问,都不会导致资源的耗尽和宕机。
三、NIO(多路复用器Selector)
Java NIO的实现关键是通过多路复用IO技术实现的,多路复用的核心就是通过Selector来轮询注册在其上的Channel,当发现某个或者多个Channel处于就绪状态后,从阻塞状态返回就绪的Channel的选择键集合,进行IO操作。
所有的 IO 在NIO 中都从一个Channel 开始。Channel 有点象流。 数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。
Selector允许单线程处理多个Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。
这是在一个单线程中使用一个Selector处理3个Channel的图示:
四、AIO异步IO
五、几种IO模型对比
BIO | NIO | AIO 以Java的角度,理解如下:
- BIO,同步阻塞式IO,简单理解:一个线程处理一个连接,发起和处理IO请求都是同步的
- NIO,同步非阻塞IO,简单理解:一个线程处理多个连接,发起IO请求是非阻塞的但处理IO请求是同步的
- AIO,异步非阻塞IO,简单理解:一个有效请求一个线程,发起和处理IO请求都是异步的
1 BIO模型中通过Socket和ServerSocket完成套接字通道实现。阻塞,同步,连接耗时。
2 NIO模型中通过SocketChannel和ServerSocketChannel完成套接字通道实现。非阻塞/阻塞,同步,避免TCP建立连接使用三次握手带来的开销。
3 AIO模型中通过AsynchronousSocketChannel和AsynchronousServerSocketChannel完成套接字通道实现。非阻塞,异步
BIO 阻塞同步通信模式,客户端和服务器连接需要三次握手,使用简单,但吞吐量小
NIO 非阻塞同步通信模式,客户端与服务器通过Channel连接,采用多路复用器轮询注册的Channel。提高吞吐量和可靠性。
AIO 非阻塞异步通信模式,NIO的升级版,采用异步通道实现异步通信,其read和write方法均是异步方法。
六、抄录网址
Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)
I/O模型系列之三:IO通信模型BIO NIO AIO的更多相关文章
- [转]BIO/NIO/AIO的几个思考
原文:https://www.jianshu.com/p/ff29e028af07 ----------------------------------------------------- BIO/ ...
- Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?
IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...
- 3. 彤哥说netty系列之Java BIO NIO AIO进化史
你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...
- IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)
有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...
- BIO,NIO,AIO总结
熟练掌握 BIO,NIO,AIO 的基本概念以及一些常见问题是你准备面试的过程中不可或缺的一部分,另外这些知识点也是你学习 Netty 的基础. BIO,NIO,AIO 总结 1. BIO (Bloc ...
- BIO,NIO,AIO 总结
BIO,NIO,AIO 总结 Java 中的 BIO.NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装.程序员在使用这些 API 的时候,不需要关心操作系统层面的知识,也不 ...
- (转)也谈BIO | NIO | AIO (Java版)
原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...
- 也谈BIO | NIO | AIO (Java版--转)
关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...
- Netty5序章之BIO NIO AIO演变
Netty5序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使 ...
随机推荐
- PMM Client 安装异常报错
1.PMM架构 如下图所示 2.Client主要组件 PMM Client是安装在你要监视的MySQL或MongoDB主机上的一组代理组件.组件收集关于一般系统和数据库性能的各种数据,并将该数据发送到 ...
- zoomeye搜索+用selenium实现对佳能打印机的爬虫
本文仅用于学习参考.要遵纪守法哦! 目的:找出一台佳能打印机,得到它的日志文件,并利用其远程打印. 1.先用zoomeye找一个打印机出来,搜索语句:printer +country:"CN ...
- vmware 14 新安装centos7 没法联网
vmware14 刚安装好centos7后,想下载安装一些软件发现无法联网,于是就百度了一下.下面 记录下解决方法. 1 确报主机能上网. 2 设置虚拟机网络适配器 3 设置虚拟机网卡 4 修改cen ...
- 网络浅析(<<网络是怎么连接的>> 总结)
概要 基本概念 网线 集线器 交换机 路由器 路由器和交换机 路由器和集线器 接入网 IP DNS 以太网 协议栈 网络连接过程 通信过程(浏览器 -> 服务器) 客户端和服务端 服务端的套接字 ...
- 智表(ZCELL)专业版收费说明
一.产品收费方式1.智表专业版按照部署地址授权.(IP或域名均可)2.不同版本单独计价,升级时需要补差价+升级服务费30元. 二.产品价格1.当前智表专业版最新版本为 V1.5版本,价格与上一版本相同 ...
- Linux 下查看字体
1.查看所有字体 命令:fc-list 2.查看中文字体 命令:fc-list :lang=zh 3.查看更多字体 命令:fc-match -v "AR PL UKai CN"
- 【vue】使用vue+element搭建项目,Tree树形控件使用
1.依赖安装 本例中,使用render-content进行树节点内容的自定义,因此需要支持JSX语法.(见参考资料第3个) 在Git bash中运行一下指令 cnpm install\ babel-p ...
- JS 设计模式五 -- 命令模式
概念 命令模式中的命令(command) 指的是 一个执行某些待定事情的指令. 用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 例子 假设html结构如下: &l ...
- Python两个栈实现一个队列
牛客网原题: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 实现这个算法的方式有很多种,这里就写一种比较简单易懂的:虽然可能算法和效率上不太出色,当大多数人 ...
- Ubuntu安装Navicat 12 for MySQL
环境准备 要想运行Navicat,必须先安装Wine,这个可以使用下面的命令来安装Wine: ubuntu@ubuntu ~ $ sudo apt-get install wine-stable 安装 ...